npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

mirror-type

v0.1.5

Published

Automatically sync database schema to TypeScript types and central platform

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-type

Quick Start

1. Create an Account & Project

Before using Mirror Type, you need to set up your project on the platform:

  1. Sign up on Mirror Type platform
    Create your account at mirror-type.dev

  2. Create a new project
    Go to the dashboard and create your first project

  3. Generate 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-config

2. 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 configuration
    • url: 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/authentication
  • watch: 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 watch

CLI Commands

mirror-type init

Initialize schema sync and generate types.

npx mirror-type init
npx mirror-type init --config ./custom-config.json

mirror-type push

Push current schema to the platform.

npx mirror-type push

mirror-type diff

Show differences between current and last synced schema.

npx mirror-type diff

Example output:

Tables Added:
  + notifications

Tables Modified:
  ~ users
      + Column: phone_number
      ~ Column: name
        Old: string
        New: string | null

mirror-type watch

Watch for schema changes and auto-sync.

npx mirror-type watch
npx mirror-type watch --interval 30000  # Check every 30 seconds

mirror-type generate-config

Generate a sample configuration file.

npx mirror-type generate-config
npx mirror-type generate-config --output ./config/schema.json

Programmatic 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-key

Backend (MySQL):

DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=secret
DB_NAME=mydb
MIRROR_TYPE_PRIVATE_KEY=your-private-key

Frontend:

# 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-key

Configuration 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 dev

License

MIT

Contributing

Contributions are welcome! Please open an issue or submit a pull request.