Documentation
Migrate from deprecated @dharayush7/fireclass to the current runtime packages and v2 model API.
The original @dharayush7/fireclass package is deprecated. The current suite
separates the modeling core from Node, Next.js, and React runtime adapters.
| Application | Replacement |
|---|---|
| Node.js, Express, workers, Cloud Functions | @dharayush7/fireclass-js |
| Next.js App Router | @dharayush7/fireclass-ssr |
| React with client Firestore and realtime hooks | @dharayush7/fireclass-react |
The legacy package was Firebase Admin-only. Moving the same application to
fireclass-js is the smallest migration. Next.js and React migrations also
change the runtime boundary.
For a Node or Express application:
npm remove @dharayush7/fireclass
npm install @dharayush7/fireclass-js firebase-admin class-validator class-transformer reflect-metadataInitialize project metadata after Firebase setup exists:
npx fireclass init
npx fireclass doctorReview the generated fireclass.json
before changing imports.
Legacy applications commonly imported the model factory from a subpath:
import { getBaseModel } from "@dharayush7/fireclass/core";
import { firestore } from "./firebase.js";
export const BaseModel = getBaseModel(firestore);Use the runtime root and keep the initialized adapter available:
import "reflect-metadata";
import { createFireclass } from "@dharayush7/fireclass-js";
import { getDb } from "./firebase.js";
export const { BaseModel, adapter } = createFireclass(getDb());fireclass-js still exports getBaseModel(db) as a migration alias, so this is
also valid as an intermediate step:
import { getBaseModel } from "@dharayush7/fireclass-js";
export const BaseModel = getBaseModel(getDb());Prefer createFireclass for new code.
Remove legacy /decorators, /core, and /types subpath imports. Runtime
packages re-export the complete core API.
import { Collection } from "@dharayush7/fireclass/decorators";
import type { QueryOptions } from "@dharayush7/fireclass/types";import {
Collection,
type QueryOptions,
} from "@dharayush7/fireclass-js";Import decorators and standalone helpers directly from the SDK where they are used. Do not re-export them from the initialized local Fireclass file.
The standard model shape remains familiar:
@Collection("users")
export class User extends BaseModel<User> {
@IsEmail()
email!: string;
constructor(data?: Partial<User>) {
super(data);
Object.assign(this, data);
}
}The new base class no longer exposes a public collection property on each
instance. Advanced code can inspect class metadata instead:
import { getCollectionName } from "@dharayush7/fireclass-js";
getCollectionName(User); // "users"The legacy implementation used validateOrReject, which rejected with a raw
ValidationError[]. The current API throws ValidationFailedError and keeps
the raw array on error.errors.
try {
await user.save();
} catch (error) {
const validationErrors = error as ValidationError[];
}import {
ValidationFailedError,
} from "@dharayush7/fireclass-js";
try {
await user.save();
} catch (error) {
if (error instanceof ValidationFailedError) {
console.error(error.errors);
}
}Express applications can replace custom mapping with
fireclassErrorHandler().
| Operation | Legacy | Current |
|---|---|---|
save() | Document id | Document id |
delete() | Deleted document id | void |
findById() | Model or null | Model or null |
findMany() | Model array; query required | Model array; query optional |
deleteById() | Deleted model or null | Deleted model or null |
deleteMany() | Deleted model array | Deleted model array |
Replace code that consumes the return value of instance delete():
const deletedId = await user.delete();const deletedId = user.id;
await user.delete();The current instance keeps its in-memory id after deletion.
Existing equals, gt, gte, lt, and lte filters continue to work.
The current query API also adds:
in and notIn;arrayContains and arrayContainsAny;cursor.startAfter;findOne() and aggregate count().const users = await User.findMany({
where: {
status: { in: ["active", "invited"] },
age: { gte: 18 },
},
orderBy: { age: "asc" },
limit: 50,
});Only the first orderBy property is currently used. Firestore's operator,
index, and cursor rules still apply.
The current core exposes concrete errors:
| Legacy failure | Current error |
|---|---|
Missing @Collection | MissingCollectionError |
| Instance delete without id | MissingIdError |
| Invalid save | ValidationFailedError |
| Missing optional adapter feature | UnsupportedAdapterCapabilityError |
Catch FireclassError for one broad library branch, then narrow to concrete
classes when recovery differs.
Do not import the old Admin-bound model into Client Components. For App Router:
@dharayush7/fireclass-ssr.getFireclass() in a server-only module.serialize() or serializeList() results to clients.reviveDates from the /client subpath.Follow the Next.js App Router guide for the complete boundary.
npx fireclass doctor
npm run typecheck
npm testThen verify create, hydrated read, merge update, delete, validation error, and every production query against the Firestore emulator.
No automatic data migration
Changing packages does not rewrite Firestore documents. The current adapters continue using the decorated collection names, but application code must handle any schema changes separately.