npm package: @kyro-cms/core
Description: Astro-native headless CMS with multi-database adapters, multi-protocol APIs, and multi-vendor support
Author: Kyro CMS
Latest version: 0.1.6

# Kyro CMS

<div align="center">

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

[![npm version](https://img.shields.io/npm/v/@kyro-cms/core.svg)](https://www.npmjs.com/package/@kyro-cms/core)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)

</div>

---

## 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, MySQL, 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)

```bash
npm create kyro@latest
```

This launches an interactive wizard that asks:

- Project name
- Database (SQLite, PostgreSQL, MySQL, 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

```bash
npm install @kyro-cms/core
```

```typescript
// 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)

```typescript
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/MySQL (Production)

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

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

### MongoDB (Flexible Schemas)

```typescript
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

```bash
# 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

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

```typescript
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",
});
```

### WebSocket (Real-time)

```typescript
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

```typescript
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:

```typescript
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:

```typescript
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

```bash
# Create admin user (first-run bootstrap)
kyro auth bootstrap -e admin@example.com -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

```bash
# 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)
KYRO_ADMIN_EMAIL=admin@example.com
KYRO_ADMIN_PASSWORD=SecurePass123!
```

---

## Version History & Drafts

Track document changes with built-in versioning:

```typescript
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:

```bash
npm install @kyro-cms/admin
```

```astro
---
// 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:

```typescript
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

```typescript
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:

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

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

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

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

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

---

## Deployment

### Quick Start with Docker

```bash
# Start PostgreSQL + Redis
docker compose up -d

# Push schema to database
npm run db:push

# Create admin user
kyro auth bootstrap -e admin@example.com -p "SecurePass123!"

# Start development
npm run dev
```

### Environment Variables Required

```bash
# 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

```bash
vercel --prod
```

Environment variables:

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

### Railway

```bash
railway up
```

### Docker

```bash
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

```bash
# 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

- [Getting Started](docs/getting-started.md)
- [API Reference](docs/api.md)
- [E-Commerce Guide](docs/ecommerce.md)
- [Plugin Development](docs/plugins.md)
- [Deployment Guide](docs/deployment.md)

---

## 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](LICENSE) for details.

---

## Acknowledgments

Built with inspiration from:

- [Payload CMS](https://payloadcms.com/) - The headless CMS that pushed the industry forward
- [Strapi](https://strapi.io/) - Open source headless CMS
- [Sanity](https://www.sanity.io/) - Real-time content infrastructure