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

chadstart

v1.0.6

Published

YAML-first Backend as a Service — define your entire backend in one YAML file

Readme

ChadStart

YAML-first Backend as a Service — define your entire backend in a single YAML file.

Inspired by Manifest, ChadStart auto-generates a fully functional backend — database schema, REST API, realtime subscriptions, OpenAPI docs, file storage, plugin system, JWT authentication, and an Admin UI — from one chadstart.yaml file.

Quick Start

npm install

Docker

Run with docker run:

# Create your chadstart.yaml first (see Configuration section below), then:
docker run -p 3000:3000 \
  -e JWT_SECRET=your-secret \
  -e DB_PATH=data/chadstart.db \
  -v ./chadstart.yaml:/app/chadstart.yaml:ro \
  -v ./data:/app/data \
  ghcr.io/saulmmendoza/chadstart.com:latest

Run with docker compose:

# 1. Create a .env file with your secrets:
echo "JWT_SECRET=$(openssl rand -hex 32)" > .env

# 2. Have a chadstart.yaml ready (see Configuration section below), then:
docker compose up

See docker-compose.yml for the full example.

Create a chadstart.yaml:

name: Blog

entities:
  Admin:
    authenticable: true
    properties:
      - name
  Customer:
    authenticable: true
    properties:
      - name
      - phone

  Post:
    properties:
      - title
      - content
      - published
    policies:
      create:
        - { access: restricted, allow: Admin }
      read:
        - access: public
      update:
        - { access: restricted, allow: Admin }
      delete:
        - { access: restricted, allow: Admin }
  Comment:
    properties:
      - text
    belongsTo:
      - Post
    policies:
      create:
        - access: restricted
      read:
        - access: public

files:
  uploads:
    path: ./uploads
    public: true

Start the server:

npx chadstart dev     # development with hot-reload
npx chadstart start   # production
npx chadstart build   # validate config and print summary

What Gets Generated

From the YAML above, ChadStart automatically provides:

| Feature | URL | |---------|-----| | REST API | /api/posts, /api/comments, ... | | Auth (signup/login/me) | /auth/admin/signup, /auth/admin/login, ... | | Admin UI | /admin | | Swagger UI | /docs | | OpenAPI JSON | /openapi.json | | Realtime WebSocket | ws://localhost:3000/realtime | | File uploads | POST /files/uploads | | Health check | /health |

Authentication & User Collections

User collections are entities with authenticable: true, gaining built-in email + password fields. Each one generates its own auth endpoints.

entities:
  Admin:
    authenticable: true
    properties:
      - name          # extra fields beyond email + password
  Customer:
    authenticable: true
    properties:
      - name
      - phone

Auth Endpoints

POST /api/auth/admin/signup     { email, password, name } → { token, user }
POST /api/auth/admin/login      { email, password }       → { token, user }
GET  /api/auth/admin/me         Authorization: Bearer <token> → user

POST /api/auth/customer/signup  { email, password, ... }  → { token, user }
POST /api/auth/customer/login   ...
GET  /api/auth/customer/me      ...

Passwords are hashed with bcrypt. Tokens are signed JWT (7-day expiry by default).

Environment variables:

JWT_SECRET=<long-random-string>   # Required in production (NODE_ENV=production)
JWT_EXPIRES=7d                    # Optional — default 7d

⚠️ JWT_SECRET defaults to a well-known dev value. Always set it in production.

Entity Policies

Restrict who can read or write each entity using policies:

entities:
  Post:
    policies:
      read:
        - access: public           # anyone
      create:
        - { access: restricted, allow: Admin }  # only authenticated Admins
  Comment:
    policies:
      read:
        - access: public
      create:
        - access: restricted      # any authenticated user

Access values: | Value | Meaning | |-------|---------| | public | No auth required | | restricted | Any authenticated user | | admin | Admin entities only | | forbidden | No access |

Emoji shortcuts: 🌐 = public, 🔒 = restricted, 👨🏻‍💻 = admin, 🚫 = forbidden

Admin UI

A built-in dark-mode SPA at /admin:

  • Sidebar with all entities and user collections
  • Data table with CRUD (create, edit, delete) for every record
  • Login screen — any user collection with admin: true (default) can sign in

Multiple user collections can access the Admin UI. Set admin: false on a collection to exclude it.

REST API

Standard CRUD for every entity:

GET    /api/posts           → list all (supports query filters)
GET    /api/posts/:id       → get one
POST   /api/posts           → create
PATCH  /api/posts/:id       → update
DELETE /api/posts/:id       → delete

Filter by any property:

GET /api/posts?published=true

Realtime

Connect via WebSocket at ws://localhost:3000/realtime:

const ws = new WebSocket('ws://localhost:3000/realtime');
ws.send(JSON.stringify({ type: 'subscribe', channel: 'Post' }));
ws.onmessage = (e) => {
  const { event, data } = JSON.parse(e.data);
  // event: 'Post.created' | 'Post.updated' | 'Post.deleted'
};

Subscribe to * to receive all events.

File Storage

files:
  uploads:
    path: ./uploads
    public: true
curl -F "[email protected]" http://localhost:3000/files/uploads   # upload
GET /files/uploads/photo.jpg                                    # download

Plugin System

plugins:
  - repo: https://github.com/org/chadstart-plugin-auth
  - path: ./my-local-plugin

Plugin interface:

module.exports = {
  name: 'my-plugin',
  register(app, core) {
    app.get('/custom', (req, res) => res.json({ hello: 'world' }));
  }
};

⚠️ Remote plugins execute arbitrary code. Only load plugins from trusted sources.

YAML Schema Reference

name: string          # Required — project name
port: 3000            # Optional — default 3000

entities:
  EntityName:
    authenticable: true  # optional — makes entity a user collection with email+password
    single: true         # optional — makes entity a singleton (one record)
    properties:
      - fieldName        # string shorthand (type: string)
      - name: fieldName
        type: string|integer|number|boolean|date|json
    belongsTo:
      - OtherEntity
    policies:
      create:
        - access: public|restricted|admin|forbidden
        - { access: restricted, allow: CollectionName }
      read:
        - access: public
      update:
        - access: restricted
      delete:
        - access: restricted

files:
  bucketName:
    path: ./uploads
    public: true

public:
  folder: ./public

plugins:
  - repo: https://github.com/org/plugin
  - path: ./local-plugin

Rate Limiting

Auth endpoints: 30 req / 15 min per IP
API endpoints: 200 req / min per IP
Admin UI: 100 req / min per IP

Project Structure

chadstart/
  core/
    yaml-loader.js       # Read & parse chadstart.yaml
    schema-validator.js  # Validate YAML structure
    entity-engine.js     # Build internal model from config
    db.js                # SQLite CRUD layer
    auth.js              # JWT auth + user collection endpoints
    api-generator.js     # Generate Express REST routes with permission enforcement
    realtime.js          # WebSocket realtime subscriptions
    openapi.js           # OpenAPI 3.0 spec generator
    file-storage.js      # File upload/download routes
    plugin-loader.js     # Dynamic plugin loading
  server/
    express-server.js    # Bootstrap everything together
  admin/
    index.html           # Admin UI single-page app
  cli/
    cli.js               # npx chadstart dev|start|build
  utils/
    logger.js            # Simple leveled logger
  test/
    test.js              # Built-in tests (39)
  chadstart.yaml         # Example config

CLI

npx chadstart dev [--config path] [--port N]    # Hot-reload dev server
npx chadstart start [--config path] [--port N]  # Production server
npx chadstart build [--config path]             # Validate & summarize config

Design Principles

  • YAML-first — one file defines everything
  • Minimal dependencies — express, ws, yaml, better-sqlite3, bcryptjs, jsonwebtoken, swagger-ui-express, express-rate-limit
  • Readable code — easy to hack and extend
  • No magic — every generated route is straightforward Express code
  • Self-hosted — runs anywhere Node.js runs

License

ISC