firescope
v0.1.1
Published
A convention-first framework for Firebase apps, functions, hosting, environments, and deploys.
Readme
Firescope
Firescope is a convention-first framework for Firebase apps. It keeps Firebase's power, but removes the repetitive setup: admin SDK bootstrapping, function exports, generated Firebase config, local env loading, emulator wiring, project connection, and deploy commands.
Quick Start
npx firescope@latest init my-app
cd my-app
npm install
npm run devDeploy:
npm run connect
npm run deployApp Shape
my-app/
firescope.config.ts
src/
db.ts
functions/
hello.ts
users/
create.ts
public/
.env.localConfig
import { defineConfig } from "firescope"
export default defineConfig({
project: process.env.FIRESCOPE_PROJECT,
region: "us-central1",
runtime: "nodejs20",
functions: {
source: "src/functions",
},
hosting: {
public: "public",
cleanUrls: true,
},
})HTTP Function
import { http } from "firescope/functions"
import { data } from "../db.js"
export default http(async ({ scope, res }) => {
const snapshot = await data.collection("users", scope.db).limit(10).get()
res.json({
users: snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() })),
})
})Typed Firestore
Define your data model once. Firescope adds type-safe collections and docs without adding runtime validation or abstraction overhead.
import { defineFirestoreSchema } from "firescope"
export type AppDb = {
users: {
displayName: string
createdAt: string
}
audit: {
type: "user.created"
userId: string
createdAt: string
}
}
export const data = defineFirestoreSchema<AppDb>()await data.collection("users").add({
displayName: "Ada",
createdAt: new Date().toISOString(),
})Collection names and document shapes are checked by TypeScript. data.collection("userz") and missing required fields fail at compile time.
Callable Function
import { callable } from "firescope/functions"
export default callable<{ name: string }>(async ({ data }) => {
return { message: `Hello ${data.name}` }
})Firestore Trigger
import { firestore } from "firescope/functions"
import { data } from "../db.js"
export default firestore.document("users/{userId}").onCreate(async ({ event, scope }) => {
await data.collection("audit", scope.db).add({
type: "user.created",
userId: event.params.userId,
createdAt: new Date().toISOString(),
})
})event.params.userId is inferred from "users/{userId}". Rename the path param and TypeScript forces the handler to follow.
CLI
firescope init scaffold an app
firescope connect login, select project, write config, enable APIs
firescope dev build and start Firebase emulators
firescope build generate Firebase-compatible output
firescope deploy build and deploy
firescope doctor validate local setupGenerated apps install firebase-tools locally, so npm run dev works without a global Firebase CLI. Local dev uses the demo project demo-firescope until you run firescope connect. firescope connect can also use gcloud to enable required Firebase/GCP APIs automatically.
What Firescope Generates
firebase.json
.firebaserc
firestore.rules
storage.rules
.firescope/
functions/
package.json
src/index.ts
lib/index.jsThe generated Functions package is what Firebase deploys. The source app stays clean.
Firescope bundles its own runtime helpers into the generated Functions output and leaves Firebase packages external. That keeps deploy output self-contained while preserving Firebase's runtime packages.
Firescope also writes safe default firestore.rules and storage.rules files when they are missing. The defaults are closed (allow read, write: if false) so emulators start without accidentally opening production data. Customize those files when your client app needs direct Firestore or Storage access.
Function Discovery
Every supported source file under src/functions is treated as a Firebase function export by default:
src/functions/hello.ts -> hello
src/functions/users/created.ts -> usersCreatedUse underscore-prefixed files or folders for local helpers that should not become functions:
src/functions/_shared/audit.ts
src/functions/users/_helpers.tsEnvironment Files
Firescope loads env files in this order, with later files winning over earlier files:
.env
.env.local
.env.<mode>
.env.<mode>.localExisting shell environment variables are preserved by default. Pass override: true to loadEnv when file values should replace existing process values.
Local Credentials
Do not commit service account JSON files. Prefer emulators locally and Firebase runtime credentials in production.
Optional local admin credential support exists for advanced cases:
FIRESCOPE_SERVICE_ACCOUNT=./secrets/service-account.json
FIRESCOPE_STORAGE_BUCKET=my-app.appspot.comCurrent Status
This is the first working framework version. It is intentionally small: conventions, CLI, runtime scope, typed Firestore helpers, typed function wrappers, generated Firebase config, generated deploy output, and onboarding checks.
Release
Publish to npm first so npx firescope@latest init my-app can install the CLI:
npm login
npm publish --access publicThe package name firescope must be available on npm. If it is published successfully, users can run:
npx firescope@latest init my-appReleases are created from version tags:
git tag v0.1.1
git push origin v0.1.1The release workflow runs type checks, tests, builds an npm tarball, and publishes a GitHub release.
GitHub Pages
The project page is served from docs/ on main: https://maskjelly.github.io/firescope/
