mirror-type
v0.1.5
Published
Automatically sync database schema to TypeScript types and central platform
Maintainers
Readme
Mirror Type
Automatically synchronize your database schema to TypeScript types and a central platform.
Perfect for full-stack development: Generate types from your database on the backend and fetch them on the frontend - all automatically in development mode!
Features
- 🎯 Backend & Frontend Modes: Generate types from DB (backend) or fetch from platform (frontend)
- 🗄️ Multi-Database Support: Works with PostgreSQL and MySQL
- 🔄 Auto Type Generation: Converts database schema to TypeScript interfaces
- 📊 Multiple Operation Types: Select, Insert, InsertUnchecked, Update, UpdateUnchecked (Prisma-style)
- 🔍 Schema Diffing: Detect and display schema changes
- ☁️ Platform Sync: Push/pull types to/from central API
- 👀 Watch Mode: Monitor changes in real-time
- 🔒 Dev-Only: Automatically disabled in production (NODE_ENV check)
- 🛠️ CLI & Programmatic API: Use via command line or integrate into your code
Installation
npm install mirror-typeQuick Start
1. Create an Account & Project
Before using Mirror Type, you need to set up your project on the platform:
Sign up on Mirror Type platform
Create your account at mirror-type.devCreate a new project
Go to the dashboard and create your first projectGenerate API keys
In your project settings, generate your API keys:- Private Key: Use in your backend (keep it secret!)
- Public Key: Use in your frontend (can be shared)
2. Choose Your Mode
Backend Mode: Generate types from your database and sync to platform
Frontend Mode: Fetch types from platform
Backend Setup
Choose your database and follow the integration guide:
PostgreSQL
Add Mirror Type to your backend application entry point (e.g., src/index.ts or src/main.ts):
import { initMirrorTypeSync } from "mirror-type";
// Initialize Mirror Type (only runs in development)
if (process.env.NODE_ENV === "development") {
await initMirrorTypeSync({
mode: "backend",
db: {
url: process.env.DATABASE_URL!,
type: "postgres",
},
privateKey: process.env.MIRROR_TYPE_PRIVATE_KEY!,
watch: true, // Auto-sync on schema changes
watchInterval: 180000, // Check every 3 minutes
});
}
// Your app code continues...MySQL
Add Mirror Type to your backend application entry point (e.g., src/index.ts or src/main.ts):
import { initMirrorTypeSync } from "mirror-type";
// Initialize Mirror Type (only runs in development)
if (process.env.NODE_ENV === "development") {
await initMirrorTypeSync({
mode: "backend",
db: {
host: process.env.DB_HOST!,
port: 3306,
user: process.env.DB_USER!,
password: process.env.DB_PASSWORD!,
database: process.env.DB_NAME!,
type: "mysql",
},
privateKey: process.env.MIRROR_TYPE_PRIVATE_KEY!,
watch: true, // Auto-sync on schema changes
watchInterval: 180000, // Check every 3 minutes
});
}
// Your app code continues...Frontend Setup
Next.js (App Router)
⚠️ Important: With Next.js, the initialization must be placed in a Server-Side component.
1. Modify app/page.tsx
Transform your main page into an async server component:
import { initMirrorTypeSync } from "mirror-type";
import ChildComponent from "./childComponent";
export default async function RootLayout() {
// Initialize Mirror Type (only runs in development)
if (process.env.NODE_ENV === "development") {
await initMirrorTypeSync({
mode: "frontend",
publicKey: process.env.NEXT_PUBLIC_MIRROR_TYPE_PUBLIC_KEY!,
outputPath: "./src/types/schema.d.ts",
watch: true,
watchInterval: 120000, // Check every 2 minutes
});
}
return <ChildComponent />;
}2. Create app/childComponent.tsx
Move your page content to a child component:
"use client"; // Optional: use if you need client-side features
export default function ChildComponent() {
return <div>{/* Your page content */}</div>;
}💡 Why this architecture? Types are generated server-side before rendering, ensuring proper synchronization.
React (Vite / Create React App)
🚀 Coming Soon - React support will be available in the next release!
Vue.js (Vite)
🚀 Coming Soon - Vue.js support will be available in the next release!
Using Configuration File (Optional)
💡 Note: The configuration file is only used for manual CLI commands. For programmatic usage in your code, pass the configuration directly to
initMirrorTypeSync().
If you prefer using CLI commands with a configuration file:
1. Generate configuration file:
npx mirror-type generate-config2. Backend Configuration (PostgreSQL):
{
"mode": "backend",
"db": {
"url": "postgresql://user:password@localhost:5432/mydb",
"type": "postgres"
},
"privateKey": "your-private-key",
"watch": true,
"watchInterval": 60000,
"outputPath": "./generated/schema.d.ts"
}Backend Configuration (MySQL):
{
"mode": "backend",
"db": {
"host": "localhost",
"port": 3306,
"user": "root",
"password": "password",
"database": "mydb",
"type": "mysql"
},
"privateKey": "your-private-key",
"watch": true,
"watchInterval": 60000,
"outputPath": "./generated/schema.d.ts"
}Configuration options:
mode: Must be"backend"db: Database connection configurationurl: Connection URL (PostgreSQL only)type: Database type ("postgres"or"mysql")host: Database host (MySQL only)port: Database port (MySQL only)user: Database user (MySQL only)password: Database password (MySQL only)database: Database name (MySQL only)
privateKey: Your private key for encryption/authenticationwatch: Enable automatic synchronization (default:false)watchInterval: Check interval in milliseconds (default:60000= 1 minute)outputPath: Path where TypeScript types will be generated (default:"./generated/schema.d.ts")
Frontend Configuration:
{
"mode": "frontend",
"publicKey": "your-public-key",
"watch": true,
"watchInterval": 120000,
"outputPath": "./src/types/schema.d.ts"
}3. Run CLI commands:
# Initialize and sync
npx mirror-type init
# Push schema (backend only)
npx mirror-type push
# Show schema diff (backend only)
npx mirror-type diff
# Watch for changes
npx mirror-type watchCLI Commands
mirror-type init
Initialize schema sync and generate types.
npx mirror-type init
npx mirror-type init --config ./custom-config.jsonmirror-type push
Push current schema to the platform.
npx mirror-type pushmirror-type diff
Show differences between current and last synced schema.
npx mirror-type diffExample output:
Tables Added:
+ notifications
Tables Modified:
~ users
+ Column: phone_number
~ Column: name
Old: string
New: string | nullmirror-type watch
Watch for schema changes and auto-sync.
npx mirror-type watch
npx mirror-type watch --interval 30000 # Check every 30 secondsmirror-type generate-config
Generate a sample configuration file.
npx mirror-type generate-config
npx mirror-type generate-config --output ./config/schema.jsonProgrammatic Usage
Backend Mode (Generate from DB)
import { initMirrorTypeSync } from "mirror-type";
// Only runs in development (NODE_ENV === 'development')
const sync = await initMirrorTypeSync({
mode: "backend",
db: {
url: process.env.DATABASE_URL,
type: "postgres",
},
privateKey: "your-private-key",
watch: true, // Watch for DB schema changes
});Frontend Mode (Fetch from Platform)
import { initMirrorTypeSync } from "mirror-type";
// Only runs in development (NODE_ENV === 'development')
const sync = await initMirrorTypeSync({
mode: "frontend",
publicKey: "your-public-key",
outputPath: "./src/types/schema.d.ts",
watch: true, // Watch for updates from platform
watchInterval: 120000, // Check every 2 minutes
});Watch Mode
import { initMirrorTypeSync } from "mirror-type";
const sync = await initMirrorTypeSync({
mode: "backend",
db: {
url: "postgresql://user:password@localhost:5432/mydb",
type: "postgres",
},
privateKey: "your-private-key",
watch: true,
watchInterval: 60000, // 1 minute
});
// Later, to stop watching:
sync.stopWatching();Manual Operations
import { MirrorTypeSync } from "mirror-type";
const sync = new MirrorTypeSync({
mode: "backend",
db: {
url: "postgresql://user:password@localhost:5432/mydb",
type: "postgres",
},
privateKey: "your-private-key",
});
// Push schema
await sync.push();
// Show diff
await sync.diff();Integration Examples
NestJS Integration
// src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { initMirrorTypeSync } from "mirror-type";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Initialize (only in development)
if (process.env.NODE_ENV === "development") {
await initMirrorTypeSync({
mode: "backend",
db: {
url: process.env.DATABASE_URL,
type: "postgres",
},
privateKey: process.env.MIRROR_TYPE_PRIVATE_KEY,
watch: true,
watchInterval: 180000,
});
}
await app.listen(3000);
}
bootstrap();Express Integration
// src/index.ts
import express from "express";
import { initMirrorTypeSync } from "mirror-type";
const app = express();
async function startServer() {
// Initialize (only in development)
if (process.env.NODE_ENV === "development") {
await initMirrorTypeSync({
mode: "backend",
db: {
url: process.env.DATABASE_URL,
type: "postgres",
},
privateKey: process.env.MIRROR_TYPE_PRIVATE_KEY,
watch: true,
watchInterval: 180000,
});
}
app.listen(3000, () => {
console.log("Server running on port 3000");
});
}
startServer();TypeORM Integration
import { DataSource } from "typeorm";
import { MirrorTypeSync } from "mirror-type";
const dataSource = new DataSource({
type: "postgres",
host: "localhost",
port: 5432,
username: "postgres",
password: "password",
database: "mydb",
entities: [
/* ... */
],
synchronize: true,
});
await dataSource.initialize();
// Sync schema after TypeORM initialization
const sync = new MirrorTypeSync({
mode: "backend",
db: {
url: "postgresql://postgres:password@localhost:5432/mydb",
type: "postgres",
},
privateKey: process.env.MIRROR_TYPE_PRIVATE_KEY,
watchInterval: 180000,
});
await sync.push();Generated Types Example
Given a database with users and orders tables:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL,
name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
total DECIMAL(10, 2) NOT NULL,
status VARCHAR(50) DEFAULT 'pending'
);The generated TypeScript types will be:
/**
* Auto-generated TypeScript types from database schema
* Generated at: 2025-11-27T10:30:00.000Z
* Schema version: a1b2c3d4e5f6
*/
export interface Orders {
id: number; // Primary Key
user_id: number | null; // Foreign Key -> users.id
total: number;
status: string | null;
}
export interface Users {
id: number; // Primary Key
email: string;
name: string | null;
created_at: Date | null;
}Environment Variables
You can override configuration with environment variables:
Backend (PostgreSQL):
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
MIRROR_TYPE_PRIVATE_KEY=your-private-keyBackend (MySQL):
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=secret
DB_NAME=mydb
MIRROR_TYPE_PRIVATE_KEY=your-private-keyFrontend:
# Next.js
NEXT_PUBLIC_MIRROR_TYPE_PUBLIC_KEY=your-public-key
# React (coming soon)
REACT_APP_MIRROR_TYPE_PUBLIC_KEY=your-public-key
# Vue/Vite (coming soon)
VITE_MIRROR_TYPE_PUBLIC_KEY=your-public-keyConfiguration Options
| Option | Type | Default | Description |
| --------------- | ------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------ |
| mode | "backend" \| "frontend" | - | Mode: backend or frontend |
| db.type | "postgres" \| "mysql" | - | Database type (backend only) |
| db.url | string | - | PostgreSQL connection URL (backend, postgres only) |
| db.host | string | - | Database host (backend, MySQL only) |
| db.port | number | 3306 | Database port (backend, MySQL only) |
| db.user | string | - | Database user (backend, MySQL only) |
| db.password | string | - | Database password (backend, MySQL only) |
| db.database | string | - | Database name (backend, MySQL only) |
| privateKey | string | - | Private API key for authentication (backend only) |
| publicKey | string | - | Public API key for authentication (frontend only) |
| watch | boolean | false | Enable watch mode |
| watchInterval | number | 60000 | Watch interval in ms (120000 recommended for frontend) |
| outputPath | string | backend: ./generated/schema.d.tsfrontend: ./src/types/schema.d.ts | Output path for generated types |
Type Mapping
PostgreSQL
| PostgreSQL Type | TypeScript Type |
| ------------------------------------------------ | --------------- |
| integer, bigint, smallint, serial | number |
| numeric, decimal, real, double precision | number |
| varchar, char, text, uuid | string |
| boolean | boolean |
| date, timestamp, time | Date |
| json, jsonb | any |
MySQL
| MySQL Type | TypeScript Type |
| --------------------------------------- | --------------- |
| int, tinyint, smallint, bigint | number |
| decimal, numeric, float, double | number |
| varchar, char, text | string |
| boolean, bool | boolean |
| date, datetime, timestamp | Date |
| json | any |
Development
# Install dependencies
npm install
# Build the package
npm run build
# Run in development mode
npm run devLicense
MIT
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
