Package Exports
- firelordjs
- firelordjs/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (firelordjs) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme

FirelordJS ็็ซๅJS
FirelordJS
FirelordJS is the only library capable of providing truly generic type safety while exposing almost all the API of the official Firestore SDK. The goal is to end Firestore typing madness.
Example of how Firelord transforms ServerTimestamp
type in different operations:
FirelordJS:
- Learning curve is the lowest (API is nearly identical to the original API).
- Technical debt is the lowest (easy to revert to the official API).
- Minimum types creation and no type assertion.
- Offers truly generic type safe solutions, declare any data shape.
- Supports deeply nested object type:
Record<string,Record<string,Record<string,...>>>
, max 1000 levels. - Supports deeply nested sub collection, all children can track back all their ancestors type, max 100 generations.
- Generates all possible flatten paths combinations based on your declared type(e.g.:
a
,a.b
,a.b.c
,a.b.d
,a.x
,a.x.y
,a.x.z
) with type safety. - Generates different types for different operations, see Transformative Types for complete list of type transformations.
- Package size is the smallest.
- Doesn't need code generation and schema language, just pure Typescript.
- Supports @firebase/rules-unit-testing and emulator, no extra API is needed!
- Is tested beyond source code, we also test built files and published package. (test source code -> build -> test built files -> publish -> test published)
- No mock test, all 250 tests test against live database to ensure the highest certainty.
- Takes care pesky runtime errors like empty array errors(filter & cursors) and implicit data deletion in update operation.
- Eliminates the repetitive tasks of writing collections ID and assigning the Firestore instance.
- Blocks undocumented errors and provides over 30 custom error messages to assist you in writing proper Firestore code! Here is an example:
FirelordJS is the only library capable of typing against Firestore limitations.
Bounty
I am confident Firelord is the best among its kind in terms of best safety and developer experience. I stand behind my words, and I will buy you x cups of coffee if you:
- find something better: 200 cups
- created something better: 2000 cups.
The bounty has been available and keeps increasing since July 14, 2022.
ESM? CommonJS?
(Web version's issue only, admin can skip this section)
FirelordJS built files are a bit complicated. It is not an ESM module(no "type":"module"
in package.json
) but it also does not transpile import
statements to CommonJS.
Results tested with various build tools:
- (Default) Non ESM with
import
statements (Pseudo ESM)
- โ
works with
create-react-app
- โ
works with
@vitejs/plugin-react-swc
- โ
works with
@sveltejs/vite-plugin-svelte
- โ
works with
nextjs
withnext-transpile-modules
- โ does not work with
@sveltejs/kit/vite
- Real ESM (Not available on NPM)
- โ
works with
@vitejs/plugin-react-swc
- โ
works with
@sveltejs/vite-plugin-svelte
- โ
works with
nextjs
withnext-transpile-modules
- โ does not work with
create-react-app
, see issue - โ does not work with
@sveltejs/kit/vite
see issue
- CommonJS
- โ does not work with
create-react-app
- โ does not work with
@vitejs/plugin-react-swc
- โ does not work with
@sveltejs/vite-plugin-svelte
- โ
works with
nextjs
. - โ
works with
@sveltejs/kit/vite
Using CommonJS Firelord with Firebase v9.17.0 and beyond break most of the build tools because of this Firebase issue
Pseudo ESM has the highest compatibility which is why it is the default package.
If you see cannot use import statement outside a module
error, please install the CommonJS version with
npm i firelordjs@cjs
Record<string, something> Support
By design Firelord banned mapped type, this was until version 2.5.10. To understand why mapped was banned in the first place and why it is possible now, see this issue. In short, querying mapped type requires extra information, make sure you know what you are doing. This is not a limitation, this is simply how things work.
Nested Composite Query Rulings
(Web version's issue only, admin can skip this section)
Rulings for or
& and
composite query are ready, rulings works with nested query, example:
Official SDK runtime error:
Firelord compile time error:
It has all the regular rulings plus new composite rulings. See also peeling composite query error messages
TO DO
Mandatory field update. Example, for field like
updatedAt
, it is mandatory to includes it every time you update the document. There are two ways to implement these feature: via Meta Type and via abstraction. With Meta Type(using special field value), it is less flexible because we no longer able to exclude it from all update operations. With abstraction, it is more flexible but require more works from user. I prefer via abstraction due to it does not shut down other use cases despite having lower user experience.Support tuple data type.
Replace
set merge
withupset
(update if exists, else set). It will receive 1 doc ref argument and 2 data arguments(partial data and complete data). It will attempt to update the document with partial data or create a document with complete data if the document does not exist.More in code documentation and tests.
Dropped TO DO
Support for object unions type. Objects unions type seem to be a good type to have in NoSQL database because of how ever-changing NoSQL schema is. However, this is not the case because it brings uncertainty that cannot be handled reasonably. For example, with
{a:number}|{b:string}
, you can set{a:1}
then update{b:"x"}
, in this case the type is no longer unions type but an intersection type:{a:number} & {b:string}
. So I will not implement this feature and will remove it from FireSageJS too. A better way to solve this is to usePossiblyReadAsUndefined
label on newly add field instead(you can also label abandoned fields asPossiblyReadAsUndefined
, but an easier way is to totally ignore them).Support for optional (
?
modifier). Optional is a highly requested feature because of how common it is, however because of how Firestore works: it is impossible to query a missing field. Example: it is impossible to query user that has no phone number if phone number field does not exist. Because of this, it is important to make sure every field exists. You may not need the field now, but you may need it later plus adding default value is simple, especially with such powerful typing library like Firelord. So in order to not accidentally cripple your query in the future, I will not implement this feature. Yes, set merge basically lead to the same problem, hence I encourage you to useupset
instead (will be available in the future).Narrow read type base on query constraint. For example
where('a', '==', true)
will narrow the read type of fielda
totrue
, it should be able to narrow down complex case likewhere('a.b.c', '==', { d:[{e:1}] })
. Expected to support==
comparator for all types and possibly!=
comparator for literal type(type filtering for!=
comparator poses great complexity hence I may not work on it). Update: I decided to give this up because with the introduction of composite query, it will be extremely difficult to implement this. Plus unlike narrowing down write type, narrowing down the read type does not contribute to type safety, it just makes thing slightly simpler(skip exhaustive check).
Trivial
- The name Firelord is a reference to the Firelord of Avatar.
- Undocumented releases are README updates.
- Contributing.
Related Projects
We are creating the best type safety tool chains for Firebase, and your support helps us make them possible:
โ
- Tested and production ready
๐ง - Done but not tested
๐
- Planning
โ๏ธ - To Rewrite
๐จ - To Repurpose (rewrite to do something else)
๐ฅ - Maintaining
๐๏ธ - Building
๐ - On Hold
โ - May Discontinue/Cancel
- FirelordJS - Typescript wrapper for Firestore Web. โ ๐ฅ
- Firelordrn - Typescript wrapper for Firestore React Native ๐งโ
- Firelord - Typescript wrapper for Firestore Admin. โ ๐ฅ
- FireSageJS - Typescript wrapper for Realtime Database Web โ
- FireSage - Typescript wrapper for Realtime Database Admin. ๐ โ
- FireSword - (new purpose) Firestore Zod Runtime Validation (Firelord Code First Approach).โ ๐ ๐จ
- FireLaw - (new purpose) Firestore Security Rules VS Code extension type linter based on Firelord type.๐๐ ๐จ
- ??? - Firelord and Firesage Front End Intergration ๐
- FireCall - Helper Function to write easier and safer Firebase onCall function.โ โ๏ธโ