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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kyro-cms/core

v0.9.0

Published

Astro-native headless CMS with multi-database adapters, multi-protocol APIs, and multi-vendor support

Readme

Kyro CMS

Astro-Native Headless CMS with Multi-Database Adapters, Multi-Protocol APIs, and Multi-Vendor Support

npm version License: MIT TypeScript


Why Kyro?

Kyro is built for Astro from the ground up. Unlike other CMS solutions that bolt on Astro support, Kyro is architected to leverage Astro's islands architecture, server output modes, and performance-first approach.

Key Features

  • Zero-Config Development - SQLite by default for instant setup, no external dependencies
  • Multi-Database - SQLite (dev), PostgreSQL, MongoDB via unified adapter interface
  • Multi-Protocol API - REST, GraphQL, tRPC, and WebSocket from a single config
  • Multi-Vendor - Built-in tenant scoping and row-level access control
  • E-Commerce Ready - Products, orders, customers, inventory, coupons out of the box
  • Plugin System - Extend with SEO, analytics, reviews, and more
  • Any Styling - Tailwind, CSS Modules, Styled Components, or plain CSS

Quick Start

Option 1: Create New Project (Recommended)

npm create kyro@latest

This launches an interactive wizard that asks:

  • Project name
  • Database (SQLite, PostgreSQL, MongoDB)
  • API protocols (REST, GraphQL, tRPC, WebSocket)
  • Styling (Tailwind, CSS Modules, Styled Components, None)
  • Authentication (JWT)
  • Versioning/Drafts
  • Admin dashboard
  • Starting template (Minimal, Blog, E-commerce)

Option 2: Add to Existing Project

npm install @kyro-cms/core
// kyro.config.ts
import { defineConfig, localAdapter } from "@kyro-cms/core";

export default defineConfig({
  name: "my-app",
  adapter: localAdapter({ path: "./data.db" }),
  collections: {
    posts: {
      slug: "posts",
      label: "Posts",
      fields: [
        { name: "title", type: "text", required: true },
        { name: "slug", type: "text", required: true },
        { name: "content", type: "richtext" },
        { name: "published", type: "checkbox", defaultValue: false },
      ],
    },
  },
  api: {
    rest: true,
    graphql: true,
  },
});

Database Adapters

SQLite (Default for Development)

import { localAdapter } from "@kyro-cms/core";

const adapter = localAdapter({
  path: "./data.db", // or ':memory:' for in-memory
});

Perfect for development and small projects. Zero configuration required - no external services needed.

PostgreSQL (Production)

import { drizzleAdapter } from "@kyro-cms/core";

const adapter = drizzleAdapter({
  connectionString: process.env.DATABASE_URL,
});

MongoDB (Flexible Schemas)

import { mongoAdapter } from "@kyro-cms/core";

const adapter = mongoAdapter({
  connectionString: process.env.MONGODB_URI,
});

API Protocols

Kyro exposes your data through multiple protocols simultaneously.

REST API

# List documents
GET /api/posts

# Get single document
GET /api/posts/:id

# Create document
POST /api/posts
{ "title": "Hello World" }

# Update document
PATCH /api/posts/:id
{ "title": "Updated Title" }

# Delete document
DELETE /api/posts/:id

GraphQL

query {
  postsFind(where: {}, page: 1, limit: 10) {
    docs {
      id
      title
      slug
    }
    totalDocs
  }
}

mutation {
  postsCreate(data: { title: "New Post", slug: "new-post" }) {
    doc {
      id
      title
    }
  }
}

tRPC

const client = createTRPCClient({
  router: kyro.router,
  transformer: superjson,
});

// Type-safe queries
const posts = await client.posts.find.query({ page: 1 });
const newPost = await client.posts.create.mutate({
  title: "Hello",
  slug: "hello",
});

Core Export Splitting (Astro Support)

To support Astro's islands architecture and prevent Node.js-only dependencies (like Redis, bcrypt, or database drivers) from crashing your browser bundle, Kyro Core provides two distinct entrypoints:

1. @kyro-cms/core (Server-Only)

Use this for backend logic, API routes, database configuration, and authentication adapters. This entrypoint includes all Node.js built-ins.

import { createKyro, drizzleAdapter, RedisAuthAdapter } from "@kyro-cms/core";

2. @kyro-cms/core/client (Browser-Safe)

Use this for Astro components, React/Vue/Svelte islands, styling, and types. This entrypoint is guaranteed to be free of Node.js dependencies.

import type { KyroConfig, CollectionConfig } from "@kyro-cms/core/client";
import { defaultLightTheme, generateCSSVariables } from "@kyro-cms/core/client";

WebSocket (Real-time)

const ws = new WebSocket("ws://localhost:4321/api/ws");

ws.send(
  JSON.stringify({
    type: "subscribe",
    collection: "posts",
    event: "create",
  }),
);

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  // Handle real-time updates
};

Field Types

Kyro supports 21 field types:

| Type | Description | | -------------- | -------------------------- | | text | Single-line text input | | textarea | Multi-line text | | richtext | Rich text editor content | | markdown | Markdown content | | number | Numeric values | | email | Email with validation | | password | Hashed password storage | | checkbox | Boolean toggle | | date | Date/time picker | | select | Dropdown selection | | radio | Radio button group | | color | Color picker | | json | JSON data | | code | Code editor content | | array | Repeatable field groups | | group | Nested field groups | | relationship | Link to other documents | | upload | File/media uploads | | blocks | Structured content blocks | | row | Horizontal field layout | | collapsible | Collapsible field sections | | tabs | Tabbed interface |

Example: Complex Fields

fields: [
  { name: "title", type: "text", required: true },

  {
    name: "author",
    type: "relationship",
    relationTo: "users",
    required: true,
  },

  {
    name: "tags",
    type: "array",
    fields: [
      { name: "name", type: "text" },
      { name: "slug", type: "text" },
    ],
  },

  {
    name: "metadata",
    type: "group",
    fields: [
      { name: "views", type: "number", defaultValue: 0 },
      { name: "featured", type: "checkbox" },
    ],
  },
];

E-Commerce Collections

Pre-built collections for building online stores:

import { ecommerceCollections } from "@kyro-cms/core";

const kyro = createKyro({
  adapter: localAdapter({ path: "./store.db" }),
  collections: ecommerceCollections,
});

// Includes:
// - products (with variants, pricing, inventory)
// - categories (hierarchical)
// - customers (with addresses)
// - orders (with items, status tracking)
// - coupons (percentage, fixed, free shipping)
// - store settings (globals)

Authentication

Built-in JWT authentication with multiple storage options:

import { RedisAuthAdapter, SQLiteAuthAdapter } from "@kyro-cms/core";
import { createAuthConfig } from "@kyro-cms/core";

// Use SQLite for development (zero-config, default)
const adapter = new SQLiteAuthAdapter({ path: "./data.db" });

// Use Redis for sessions (recommended for production)
const redisAdapter = new RedisAuthAdapter({
  url: process.env.REDIS_URL,
  tls: process.env.REDIS_TLS === "true",
});

// Or use PostgreSQL for production
import { PostgresAuthAdapter, createDatabase } from "@kyro-cms/core";

const { db } = await createDatabase();
const pgAdapter = new PostgresAuthAdapter({ db });

// Or use env-based config with all features
const authConfig = await createAuthConfig();
const { redis, routes, passwordPolicy, lockout } = authConfig;

Authentication Features

  • JWT Tokens - 24h expiry with refresh token support
  • Multiple Storage Options - SQLite (dev), Redis, PostgreSQL via unified adapter interface
  • Password Policy - 12+ chars, complexity requirements, history check
  • Account Lockout - 5 failed attempts → 15 minute lockout
  • Rate Limiting - Per-IP and per-user limits
  • Audit Logging - 30-day retention with action tracking

CLI Commands

# Create admin user (first-run bootstrap)
kyro auth bootstrap -e [email protected] -p "SecurePass123!" -r admin

# Database setup
kyro db migrate    # Run migrations
kyro db push       # Push schema to database
kyro db seed       # Seed default roles
kyro db studio     # Open Drizzle Studio

RBAC Roles (Hierarchy)

super_admin (100) > admin (90) > editor (70) > author (50) > customer (30) > guest (10)

Environment Variables

# Database
DATABASE_URL=postgresql://user:pass@host:5432/kyro_cms
DATABASE_SSL=false

# Redis (sessions/cache)
REDIS_URL=redis://localhost:6379
REDIS_TLS=false

# JWT
JWT_SECRET=your-32-char-secret
JWT_EXPIRES_IN=24h

# Auth Settings
LOCKOUT_MAX_ATTEMPTS=5
LOCKOUT_DURATION_MINUTES=15
PASSWORD_MIN_LENGTH=12

# Bootstrap (first-run admin)
[email protected]
KYRO_ADMIN_PASSWORD=SecurePass123!

Version History & Drafts

Track document changes with built-in versioning:

import { createVersionManager } from "@kyro-cms/core";

const versions = createVersionManager(adapter, {
  versioningEnabled: true,
  maxVersionsPerDocument: 50,
});

// Create a new version
const version = await versions.createVersion({
  collection: "posts",
  documentId: "abc123",
  data: { title: "Updated Post" },
  status: "draft",
  createdBy: "user123",
});

// Publish
await versions.publishVersion({
  collection: "posts",
  documentId: "abc123",
  versionId: version.id,
  publishedBy: "user123",
});

Admin Dashboard

Kyro includes a full admin dashboard:

npm install @kyro-cms/admin @kyro-cms/core

The admin uses local utilities for API calls, date formatting, and validation.

---
// admin/index.astro
import { Admin } from '@kyro-cms/admin';
import config from '../kyro.config';
---

<Admin client:load config={config} />

Features:

  • Collection browser with filtering and sorting
  • Document editor with all field types
  • Media library
  • Global settings editor
  • Dark mode support

Plugin System

Extend Kyro with plugins:

import {
  KyroPlugin,
  SEOPLugin,
  AnalyticsPlugin,
  CommentsPlugin,
  ReviewsPlugin,
  WishlistPlugin
} from '@kyro-cms/core';

const kyro = createKyro({
  adapter: localAdapter(),
  collections: [...],
  plugins: [
    new SEOPLugin({
      sitemap: true,
      robotsTxt: true,
    }),
    new AnalyticsPlugin({
      providers: ['google', 'plausible'],
    }),
    new CommentsPlugin(),
    new ReviewsPlugin(),
  ],
});

Creating Plugins

import { KyroPlugin } from "@kyro-cms/core";

class MyPlugin extends KyroPlugin {
  name = "my-plugin";

  hooks = {
    "collection.beforeCreate": async (args) => {
      // Transform data before creation
      return { ...args, data: { ...args.data, source: "my-plugin" } };
    },

    "document.afterSave": async (args) => {
      // Send webhook, log analytics, etc.
      await sendWebhook(args);
    },
  };
}

Styling System

Kyro ships with a complete styling system:

import {
  ecommerce2026Theme,
  generateCSSVariables,
  generateTailwindConfig,
} from "@kyro-cms/core/client";

// Generate CSS variables
const cssVars = generateCSSVariables(ecommerce2026Theme);

// Generate Tailwind config
const tailwindConfig = generateTailwindConfig(ecommerce2026Theme);

// Custom themes
import { createAdminStyling } from "@kyro-cms/core/client";

const myTheme = createAdminStyling({
  primaryColor: "#6366f1",
  borderRadius: "medium",
  fontFamily: "Inter",
});

Deployment

Quick Start with Docker

# Start PostgreSQL + Redis
docker compose up -d

# Push schema to database
npm run db:push

# Create admin user
kyro auth bootstrap -e [email protected] -p "SecurePass123!"

# Start development
npm run dev

Environment Variables Required

# Database (PostgreSQL)
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/kyro_cms
DATABASE_SSL=false

# Redis (sessions/cache) - supports Redis Cloud
REDIS_URL=redis://localhost:6379
REDIS_TLS=false

# JWT (required)
JWT_SECRET=change-me-in-production-min-32-chars

Vercel

vercel --prod

Environment variables:

  • DATABASE_URL - PostgreSQL connection string
  • JWT_SECRET - JWT signing secret

Railway

railway up

Docker

cd deployments/docker
docker-compose up -d

See deployments/ for complete configuration.


Project Structure

kyro-cms/
├── packages/
│   └── create-kyro/        # Project scaffolding CLI
├── src/
│   ├── index.ts             # Main exports
│   ├── createKyro.ts        # Factory function
│   ├── registry/            # Config registry & validation
│   ├── fields/              # 21 field type definitions
│   ├── database/            # Adapter implementations
│   │   ├── local/           # SQLite adapter
│   │   ├── drizzle/         # SQL adapters
│   │   └── mongodb/         # MongoDB adapter
│   ├── api/                 # Multi-protocol gateway
│   │   ├── rest/            # Hono REST
│   │   ├── graphql/         # GraphQL schema
│   │   ├── trpc/            # tRPC router
│   │   └── ws/              # WebSocket server
│   ├── auth/                # JWT authentication
│   ├── versions/            # Version history
│   ├── plugins/             # Plugin system
│   ├── styling/             # Theming
│   └── cli/                 # CLI tools
├── admin/                   # Admin dashboard (Astro)
├── examples/                # Example configurations
├── docs/                    # Documentation
└── deployments/             # Deployment configs

CLI Commands

# Initialize a new project
npm create kyro@latest

# Generate TypeScript types
kyro generate

# Push schema to database
kyro push

# Open database studio
kyro studio

# Check system health
kyro health

Documentation


Contributing

Contributions are welcome! Please read our contributing guide before submitting PRs.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing)
  5. Open a Pull Request

License

MIT License - see LICENSE for details.


Acknowledgments

Built with inspiration from:

  • Payload CMS - The headless CMS that pushed the industry forward
  • Strapi - Open source headless CMS
  • Sanity - Real-time content infrastructure