Generate TypeScript types from your Pydantic models for the Firestore documents you read in realtime -- and fail CI on schema changes that would break a frontend still reading the old shape (FULL_TRANSITIVE).
Project description
firepact
Keep your Pydantic backend and your TypeScript frontend agreeing on the
wire shape of Firestore Native-mode documents read in realtime via
onSnapshot — and fail CI on a schema change that would break a frontend still
reading the old shape (FULL_TRANSITIVE).
firepact is not just a type converter. It generates the TypeScript types your frontend imports and runs a compatibility gate over the contract as it evolves. Before you rely on the green check, read what firepact is — and is not: it gates the evolution of the contract, not the data already sitting in Firestore.
Install
pip install firepact # Python CLI (firepact-gen / firepact-compat) + native engine
cargo install firepact-core # standalone Rust binary `firepact` (no Python/Node)
Quick start
1. Mark the models you read in realtime. The decorator records the collection path and which fields are guaranteed on every document; the backend writes with a camelCase alias generator (firepact matches it).
from datetime import datetime
from typing import Annotated
from firepact import firestore_realtime, FirestoreServerTimestamp
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
class CamelModel(BaseModel): # camelCase wire keys
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
@firestore_realtime(collection="rooms/{roomId}/messages", guaranteed=["body"])
class Message(CamelModel):
id: str # document id
body: str
created_at: Annotated[datetime, FirestoreServerTimestamp()]
tags: list[str] = []
2. Generate the TypeScript your frontend imports.
firepact-gen --module app.models --output src/firestore.ts
// @firestore-collection rooms/{roomId}/messages
export interface Message { // read view, for onSnapshot()
body: string; // guaranteed -> required even on old docs
createdAt?: Timestamp | null; // server timestamp: null until it resolves
id: string; // the converter injects snapshot.id
tags?: string[]; // not guaranteed -> optional (safe default)
}
export interface MessageWrite { // write view, for setDoc(): id is excluded
body: string;
createdAt: FieldValue; // serverTimestamp()
tags: string[];
}
The full worked example (refs, open enums, discriminated unions, vectors,
GeoPoints, bytes) is in examples/gen/chat/.
3. Gate compatibility in CI. Export the contract bundle per release and diff each change against the committed history; a breaking change fails CI.
firepact-gen --module app.models --bundle-out schemas/v2.json
firepact-compat --history schemas --new schemas/v2.json
See usage for the read/write/update views and the converter, and the compatibility gate for what counts as breaking.
Supported versions
Verified in CI (see .github/workflows/ci.yaml).
| Component | Supported | Notes |
|---|---|---|
| Python | 3.11 – 3.14 | one abi3 wheel covers 3.11+ |
| Pydantic | 2.9 – 2.13 | drift canary; the exact schema golden is pinned to the locked version |
| JSON Schema | Draft 2020-12 | Pydantic's default dialect |
| TypeScript (output) | 5.x / 6.x / 7.x | type-checks under verbatimModuleSyntax + isolatedModules |
| firebase JS SDK | v11+ | Timestamp, GeoPoint, DocumentReference, Bytes, VectorValue, FieldValue, UpdateData, FirestoreDataConverter |
| Rust | 1.75+ | MSRV (Cargo.toml) |
Dependency bumps within these ranges are tracked by Dependabot.
Documentation
- scope — what firepact is and is not (read this first)
- usage — annotating models, the read/write/update views, the gate
- contract & projection — the
x-firestore-*vocabulary - compatibility — the
FULL_TRANSITIVEgate and its taxonomy - architecture — the two components and the single bundle
docs/adr/— the decisions (the "Why")
How it works
firepact-core(Rust crate, binaryfirepact): pure, Python/Node-free.firepact emitprojects one enriched JSON Schema bundle into read/write/update TypeScript;firepact compatis the gate.firepact(Python package): imports your Pydantic models, delegates schema generation to Pydantic, stamps thex-firestore-*vocabulary, and emits via the native core. Console scripts:firepact-gen,firepact-compat, andpydantic2ts(a drop-in alias for the prior tool).
Contributing
just build # build the Rust core + `firepact` binary
just test # all tests (rust + python)
just lint # rust + python + markdown checks
just example-gen # regenerate the generation examples (examples/gen/)
just example-compat # gate the compat example against its committed history
Prior art & license
The Firestore-specialised, from-scratch successor to pydantic-to-typescript (which targeted FastAPI request/response types and depended on Node). MIT licensed (LICENSE).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file firepact-0.1.8.tar.gz.
File metadata
- Download URL: firepact-0.1.8.tar.gz
- Upload date:
- Size: 176.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef11401025c9a1324fb71531941bc3e52301893b4ccc0fa88fe6b25e8f697d06
|
|
| MD5 |
46a28d8a38884056d6932bf8622f1c5a
|
|
| BLAKE2b-256 |
40ef99dd7de09051d32e898d813bce4fe955ac299f074c0395c8912f941b8710
|
Provenance
The following attestation bundles were made for firepact-0.1.8.tar.gz:
Publisher:
release.yaml on hironow/firepact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firepact-0.1.8.tar.gz -
Subject digest:
ef11401025c9a1324fb71531941bc3e52301893b4ccc0fa88fe6b25e8f697d06 - Sigstore transparency entry: 1735527386
- Sigstore integration time:
-
Permalink:
hironow/firepact@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/hironow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file firepact-0.1.8-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: firepact-0.1.8-cp311-abi3-win_amd64.whl
- Upload date:
- Size: 214.9 kB
- Tags: CPython 3.11+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91ab2cee0a68a7b64f20daae0f6c17e5b8c5bfc6b02c4f6944182d988e4bb193
|
|
| MD5 |
5aef70d29a1b12796be40918f785d1d6
|
|
| BLAKE2b-256 |
5e206944a3ca33163131babb91c1e07ccd6d95df6fb5fc44b341a22cd19ae158
|
Provenance
The following attestation bundles were made for firepact-0.1.8-cp311-abi3-win_amd64.whl:
Publisher:
release.yaml on hironow/firepact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firepact-0.1.8-cp311-abi3-win_amd64.whl -
Subject digest:
91ab2cee0a68a7b64f20daae0f6c17e5b8c5bfc6b02c4f6944182d988e4bb193 - Sigstore transparency entry: 1735527440
- Sigstore integration time:
-
Permalink:
hironow/firepact@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/hironow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file firepact-0.1.8-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: firepact-0.1.8-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 350.0 kB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08c2dfe6c98d4b702c54cddc3587d8d662718c00b8b81bceb1abf655fad9d6d8
|
|
| MD5 |
2dfcea9c28da663a5b28325fdcaa9002
|
|
| BLAKE2b-256 |
b07ba83d8c7d25ba8eb0e32c45ec0736ae2d8308922ee508249358cb6531fa22
|
Provenance
The following attestation bundles were made for firepact-0.1.8-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yaml on hironow/firepact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firepact-0.1.8-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
08c2dfe6c98d4b702c54cddc3587d8d662718c00b8b81bceb1abf655fad9d6d8 - Sigstore transparency entry: 1735527454
- Sigstore integration time:
-
Permalink:
hironow/firepact@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/hironow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file firepact-0.1.8-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: firepact-0.1.8-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 332.1 kB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4b18974a3d910b5474b60732a45e874573fdb49511c0b98767a8341c9aee797
|
|
| MD5 |
e35343a62cde36ddbe6b9bd5ef5928f7
|
|
| BLAKE2b-256 |
59629618248e92f2080bfe7aab308443b9df3204e462060864cd2c1e0ea5cecf
|
Provenance
The following attestation bundles were made for firepact-0.1.8-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yaml on hironow/firepact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firepact-0.1.8-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
e4b18974a3d910b5474b60732a45e874573fdb49511c0b98767a8341c9aee797 - Sigstore transparency entry: 1735527410
- Sigstore integration time:
-
Permalink:
hironow/firepact@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/hironow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file firepact-0.1.8-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: firepact-0.1.8-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 306.2 kB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd18948ed617f417078f20377f79b7b2d19f693fe13a800ac3549e51d5926e6a
|
|
| MD5 |
2097bb54f72c015057ddcae628d5d62c
|
|
| BLAKE2b-256 |
a4ef920789dd56807bc426dd24f286a220892cbf7003dca4bea462e1d8afa84d
|
Provenance
The following attestation bundles were made for firepact-0.1.8-cp311-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yaml on hironow/firepact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firepact-0.1.8-cp311-abi3-macosx_11_0_arm64.whl -
Subject digest:
cd18948ed617f417078f20377f79b7b2d19f693fe13a800ac3549e51d5926e6a - Sigstore transparency entry: 1735527464
- Sigstore integration time:
-
Permalink:
hironow/firepact@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/hironow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file firepact-0.1.8-cp311-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: firepact-0.1.8-cp311-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 321.3 kB
- Tags: CPython 3.11+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19bc7da9ab8a99814d8b24faa3f4f9cc3a2a827f738dcb8fe2e9796782a1ea67
|
|
| MD5 |
65501e176547fbdc98ac0d4dda97121f
|
|
| BLAKE2b-256 |
b5a291bcd7f4aad2f7a45d4d96d57eed6029c535da9c6dea49c4f12ceb80b821
|
Provenance
The following attestation bundles were made for firepact-0.1.8-cp311-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yaml on hironow/firepact
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firepact-0.1.8-cp311-abi3-macosx_10_12_x86_64.whl -
Subject digest:
19bc7da9ab8a99814d8b24faa3f4f9cc3a2a827f738dcb8fe2e9796782a1ea67 - Sigstore transparency entry: 1735527520
- Sigstore integration time:
-
Permalink:
hironow/firepact@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/hironow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@bdbae54aa2b1643d34e564e97639a00ce3caabd4 -
Trigger Event:
push
-
Statement type: