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

@blysspeak/prada

v1.0.0

Published

PRADA - PRisma ADmin: Modular admin panel library for PostgreSQL databases

Readme


What is PRADA?

PRADA turns any PostgreSQL database with a Prisma schema into a fully functional admin panel. It works as a library — not a framework — so you can drop it into an existing Express app, extend it with custom modules, and override any part of the UI.

Use it as a foundation. The database is already connected, CRUD already works, auth is handled. You focus on building your domain-specific admin logic on top.


Quick Start

npm install @blysspeak/prada @blysspeak/prada-ui
import express from 'express'
import { PrismaClient } from '@prisma/client'
import { createPradaServer } from '@blysspeak/prada'

const app = express()
const prisma = new PrismaClient()

app.use('/admin', await createPradaServer({
  prisma,
  auth: { login: 'admin', password: 'secret' }
}))

app.listen(3000)
// Admin panel at http://localhost:3000/admin

That's it. Every model in your Prisma schema now has list, create, edit, view, and delete pages.


Key Features

  • Zero config — auto-generates CRUD from Prisma schema
  • 3-level API — ready solution, building blocks, or primitives
  • Module system — extend backend with custom routes and middleware
  • UI customization — replace any field, cell, page, or section via a single config
  • Data hooks — React Query hooks for custom pages (useModelList, useModelCreate, etc.)
  • Multi-file schema — supports directory of .prisma files
  • JWT auth — HTTP-only cookies, refresh tokens, setup wizard
  • i18n — Russian and English out of the box
  • Themes — dark and light with animated toggle
  • Advanced filters — operator-based filtering (contains, gte, lte, in, etc.)
  • Bulk operations — mass delete and update via API
  • Stats API — per-model record counts and recent activity
  • Audit log — automatic change tracking with diff history
  • Keyboard shortcuts — navigate with hotkeys, ? for help
  • Global search — Ctrl+K command palette across all models
  • Inline editing — double-click cells to edit in place
  • Relations UI — autocomplete for foreign keys, clickable links
  • Data export — CSV/JSON export with Excel compatibility
  • Dashboard widgets — stats cards, quick actions, recent activity

Architecture

PRADA provides 3 abstraction levels. Use what fits your needs:

Level 3: Ready Solution

app.use('/admin', await createPradaServer({
  prisma,
  schemaPath: './prisma/schema',  // single file or directory
  modules: [statsModule, uploadsModule],
  audit: true,  // Enable change tracking
  hooks: {
    '*': { beforeCreate: async (data) => ({ ...data, createdAt: new Date() }) },
    User: { beforeCreate: async (data) => ({ ...data, password: await hash(data.password) }) }
  },
  models: {
    User: { actions: ['read', 'update'], fields: { password: { hidden: true } } }
  }
}))

Level 2: Building Blocks

import {
  parseSchema, createApiHandler, createCrudRoutes,
  createAuthService, createAuthMiddleware, createAuthRoutes
} from '@blysspeak/prada'

const schema = await parseSchema()
const api = createApiHandler(prisma, schema, { hooks })
const auth = createAuthService({ login: 'admin', password: 'secret' })

router.use('/api/auth', createAuthRoutes(auth))
router.use('/api', createAuthMiddleware(auth), createCrudRoutes(api))

Level 1: Primitives

import {
  buildWhereClause, buildOrderByClause, parsePagination,
  generateToken, verifyToken, hashPassword,
  getScalarFields, getIdField, getSearchableFields
} from '@blysspeak/prada'

Backend Modules

Extend the admin panel with custom backend logic:

import { Router } from 'express'
import type { PradaModule } from '@blysspeak/prada'

const statsModule: PradaModule = {
  name: 'stats',
  routes: async (ctx) => {
    const router = Router()

    router.get('/stats/overview', async (req, res) => {
      const users = await ctx.prisma.user.count()
      const orders = await ctx.prisma.order.count()
      res.json({ users, orders })
    })

    ctx.router.use('/api', ctx.authMiddleware, router)
  }
}

app.use('/admin', await createPradaServer({
  prisma,
  modules: [statsModule]
}))

The module receives PradaContext with prisma, schema, router, authMiddleware, and config.


UI Customization

The entire UI is customizable through a single PradaConfig object:

import { App } from '@blysspeak/prada-ui'

<App config={{
  // Custom form fields
  fields: {
    byType: { json: MonacoJsonEditor },
    byName: { avatar: AvatarUpload },
    byModelField: { User: { bio: RichTextEditor } }
  },

  // Custom table cells
  cells: {
    byName: { status: StatusBadge },
    byModelField: { Order: { total: CurrencyCell } }
  },

  // Replace entire pages
  pages: {
    dashboard: CustomDashboard
  },

  // Insert components into pages
  slots: {
    listHeader: ({ model }) => <StatsBar model={model} />,
    formFooter: ({ model }) => <AuditLog model={model} />
  },

  // Add custom routes (appear in sidebar)
  routes: [
    { path: '/analytics', element: AnalyticsPage,
      sidebar: { label: 'Analytics', icon: BarChart } }
  ],

  // Configure sidebar
  sidebar: {
    hiddenModels: ['_prisma_migrations'],
    modelLabels: { User: 'Team Members' },
    logo: CustomLogo
  },

  // Configure table actions
  actions: {
    rowActions: { Order: [ExportButton, RefundButton] },
    hideActions: { AuditLog: ['edit', 'delete'] }
  }
}} />

Field resolution priority: model+field > field name > field type > default component.


Data Hooks

Build custom pages with easy database access:

import {
  useModelList, useModelRecord,
  useModelCreate, useModelUpdate, useModelDelete
} from '@blysspeak/prada-ui'

function OrdersPage() {
  const { data, meta, isLoading } = useModelList('Order', {
    sort: 'createdAt',
    order: 'desc',
    filters: { status: 'pending' },
    page: 1,
    limit: 50
  })

  const { mutate: updateOrder } = useModelUpdate('Order')
  const { mutate: deleteOrder } = useModelDelete('Order')

  return (
    <div>
      <h1>Pending Orders ({meta.total})</h1>
      {data.map(order => (
        <OrderCard
          key={order.id}
          order={order}
          onApprove={() => updateOrder({ id: order.id, data: { status: 'approved' } })}
          onDelete={() => deleteOrder(order.id)}
        />
      ))}
    </div>
  )
}

API Endpoints

| Method | Endpoint | Description | |--------|----------|-------------| | GET | /api/schema | Schema metadata (models, fields, enums) | | GET | /api/:model | List records with pagination | | GET | /api/:model/:id | Get single record | | POST | /api/:model | Create record | | PUT | /api/:model/:id | Update record | | DELETE | /api/:model/:id | Delete record | | POST | /api/auth/login | Login | | POST | /api/auth/logout | Logout | | GET | /api/auth/me | Current user | | POST | /api/auth/refresh | Refresh token | | GET | /api/stats | Per-model record counts | | DELETE | /api/:model/bulk | Bulk delete records | | PUT | /api/:model/bulk | Bulk update records | | GET | /api/audit | Audit log entries | | GET | /api/audit/:model | Audit log for model | | GET | /api/audit/:model/:id | Audit log for record |

Query parameters: ?page=1&limit=20&sort=createdAt&order=desc&search=john&include=posts,comments

Supports operator filters: ?field__contains=value&field__gte=10


Documentation

English

| Document | Description | |----------|-------------| | Getting Started | Installation, basic usage, environment variables | | Architecture | 3-level abstraction, project structure, data flow | | UI Customization | PradaConfig, fields, cells, pages, slots, routes, sidebar | | Backend Modules | PradaModule, PradaContext, custom routes | | Data Hooks | useModelList, useModelRecord, useModelCreate, etc. | | API Reference | All exports, REST endpoints, TypeScript types |

Русский

| Документ | Описание | |----------|----------| | Быстрый старт | Установка, базовое использование, переменные окружения | | Архитектура | 3 уровня абстракции, структура проекта, поток данных | | Кастомизация UI | PradaConfig, поля, ячейки, страницы, слоты, роуты, сайдбар | | Модули бэкенда | PradaModule, PradaContext, кастомные роуты | | Data Hooks | useModelList, useModelRecord, useModelCreate и др. | | Справочник API | Все экспорты, REST-эндпоинты, TypeScript типы |


Packages

| Package | Description | |---------|-------------| | @blysspeak/prada | Backend — Express middleware, schema parser, CRUD API, auth, module system | | @blysspeak/prada-ui | Frontend — React components, data hooks, customization system |


Requirements

  • Node.js 18+
  • PostgreSQL
  • Prisma schema (schema.prisma or directory of .prisma files)

Development

git clone https://github.com/blysspeak/prada.git
cd prada
pnpm install
pnpm build        # Build all packages
pnpm dev          # UI dev server with hot reload
pnpm build:main   # Backend only
pnpm build:ui     # UI only

License

MIT

Author

blysspeak