Schema-driven full-stack framework for Node.js and PostgreSQL.
Status: Pre-1.0. Valence is in active development. The API surface is stabilizing but breaking changes may occur. Security hardening and package-by-package audits are ongoing.
Define collections and fields in one TypeScript config. Valence derives database tables, a server-rendered admin panel, REST and GraphQL APIs, typed routes with loaders and actions, entity codegen, database migrations, and a first-party analytics pipeline from that single schema. No runtime framework on public pages. No vendor scripts. Minimal, audited dependencies.
// valence.config.ts
import { defineConfig, collection, field } from '@valencets/valence'
export default defineConfig({
db: {
host: process.env.DB_HOST ?? 'localhost',
port: Number(process.env.DB_PORT ?? 5432),
database: process.env.DB_NAME ?? 'mysite',
username: process.env.DB_USER ?? 'postgres',
password: process.env.DB_PASSWORD ?? 'postgres',
sslmode: process.env.DB_SSLMODE as 'disable' | 'require' | 'verify-ca' | 'verify-full' | undefined,
sslrootcert: process.env.DB_SSLROOTCERT
},
server: { port: Number(process.env.PORT ?? 3000) },
collections: [
collection({
slug: 'posts',
labels: { singular: 'Post', plural: 'Posts' },
versions: { drafts: true },
hooks: {
afterChange: [({ doc }) => console.log('saved', doc.id)]
},
fields: [
field.text({ name: 'title', required: true }),
field.slug({ name: 'slug', slugFrom: 'title', unique: true }),
field.richtext({ name: 'body' }),
field.tabs({
tabs: [
{
label: 'Details',
fields: [
field.boolean({ name: 'published' }),
field.date({ name: 'publishedAt', condition: (data) => data.published === 'true' })
]
},
{
label: 'SEO',
fields: [
field.text({ name: 'metaTitle' }),
field.textarea({ name: 'metaDescription' })
]
}
]
})
]
}),
collection({
slug: 'users',
auth: true,
fields: [
field.text({ name: 'name', required: true }),
field.select({
name: 'role',
defaultValue: 'editor',
access: { update: ({ user }) => user.role === 'admin' },
options: [
{ label: 'Admin', value: 'admin' },
{ label: 'Editor', value: 'editor' }
]
})
]
})
],
routes: [
{
path: '/blog/:slug',
collection: 'posts',
type: 'detail',
loader: async ({ params, pool }) => {
const post = await pool`SELECT * FROM posts WHERE slug = ${params.slug}`
return { data: { post: post[0] } }
}
},
{
path: '/contact',
method: 'POST',
action: async ({ body }) => {
return { redirect: '/thank-you' }
}
}
],
onServer ({ server, pool, cms, registerRoute }) {
registerRoute('GET', '/api/health', (_req, res) => {
res.writeHead(200).end('ok')
})
},
admin: { pathPrefix: '/admin', requireAuth: true },
graphql: true,
telemetry: {
enabled: true,
endpoint: '/api/telemetry',
siteId: 'mysite'
}
})That config gives you: posts and users tables in Postgres, a server-rendered admin panel with form validation and session auth (Argon2id), a REST API at /api/posts and /api/users, a GraphQL endpoint at /graphql, typed routes with loaders and actions, an onServer hook for custom routes and WebSocket handlers, a typed src/ scaffold with entity interfaces and API clients, Zod validators, database migrations, draft versioning with revision history, and a first-party analytics pipeline that tracks user intent without any third-party scripts on your public pages. One schema to rule them all.
npx @valencets/valence init my-site
cd my-site
pnpm devThe init wizard walks you through database setup, admin user creation, optional seed data, and framework choice (plain HTML templates, Astro, or bring your own). Pass --yes to skip prompts and accept defaults.
Open http://localhost:3000/admin to sign in. Open http://localhost:3000 for the landing page.
- Database tables derived from your field definitions. UUID primary keys, timestamps, soft deletes.
- 22 field types. text, textarea, richtext, number, boolean, select, date, slug, media, relation, group, email, url, password, json, color, multiselect, array, blocks, tabs, row, collapsible.
- Layout fields. Tabs, rows, and collapsible sections for organizing complex admin forms without affecting the database schema.
- Conditional fields. Show or hide fields based on other field values using the
conditionfunction. - Field access control. Per-field create, read, and update access control functions that receive the current user context.
- Field hooks.
beforeValidate,beforeChange,afterChange,afterReadhooks on individual fields. - Globals. Single-document configs (site settings, navigation, footer) via
global()with the same field system. - Migrations generated from schema diffs. Deterministic SQL, idempotent, version-tracked.
- Server-rendered admin at
/admin. HTML forms, CSRF protection, session auth with Argon2id. - Rich text editor. Tiptap-powered (ProseMirror) with heading, list, blockquote, link, code, divider, and code block formatting. Slash command menu for block insertion.
- Draft versioning. Enable
versions: { drafts: true }on a collection for publish/unpublish workflow with revision history and diff view. - Autosave. Automatic draft saving with visual indicator via the
<val-autosave>component. - Live preview. Split-pane editor with real-time preview iframe via postMessage.
- Bulk operations. Select multiple documents in list view for bulk delete, publish, or unpublish.
- Image processing. Automatic image resizing and optimization via Sharp on media upload.
- REST API at
/api/:collection. CRUD with Zod validation, parameterized queries,Result<T, E>error handling. - GraphQL API. Auto-generated schema from collections with resolvers wired to the Local API. Enable with
graphql: true. - Local API. Programmatic access to all CRUD operations with the same validation and hooks as the REST layer.
- Full-text search. PostgreSQL tsvector/tsquery with relevance ranking, configurable per collection.
- Page routing.
src/pages/maps to URL paths. - Routes with loaders. Server-side data loading injected into pages.
- Routes with actions. Form handling that returns redirects or field-level errors.
onServerhook. Access the rawhttp.Server, database pool, CMS instance, andregisterRoutefor custom endpoints or WebSocket upgrade handlers.- View transitions. Built-in presets for smooth page navigation.
- 23 Web Components. ARIA-compliant, i18n-ready, telemetry hooks, hydration directives. OKLCH design tokens. Zero dependencies.
- Entity codegen. Typed interfaces and API clients generated from your schema.
// @generatedfiles regenerate on config change; user-edited files are never overwritten. - Static file serving.
public/served with MIME types and path traversal protection.
- Argon2id password hashing for admin authentication.
- CSRF protection on admin forms (double-submit cookie with
crypto.randomBytes). - Session auth with
httpOnly,Secure,SameSite=Strictcookie flags. - Path traversal protection on static file serving, media uploads, and cloud storage.
- URL redirect validation to prevent open redirect attacks.
- Parameterized SQL everywhere. No string concatenation in queries.
- CodeQL and Socket auditing in CI.
First-party analytics that runs entirely in your Postgres. No Google Analytics, no Plausible, no third-party scripts on your public pages. Your data stays in your database.
Annotate HTML elements with data-telemetry-* attributes. The client library captures events in a pre-allocated ring buffer (zero allocation in the hot path) and auto-flushes via navigator.sendBeacon(). The server ingests payloads, stores raw events, and aggregates into daily summaries.
11 intent types: CLICK, SCROLL, VIEWPORT_INTERSECT, FORM_INPUT, INTENT_NAVIGATE, INTENT_CALL, INTENT_BOOK, INTENT_LEAD, LEAD_PHONE, LEAD_EMAIL, LEAD_FORM.
@valencets/plugin-seo— auto-title, meta field injection.@valencets/plugin-nested-docs— tree structures with breadcrumb computation.@valencets/plugin-cloud-storage— S3-compatible object storage adapter.
Plugins are config transformers: a function that receives a CmsConfig and returns a modified CmsConfig.
| Package | What it does | External deps |
|---|---|---|
@valencets/ui |
23 Web Components. ARIA, i18n, telemetry hooks, hydration directives. OKLCH tokens. | none |
@valencets/core |
Router + server. pushState nav, fragment swaps, prefetch, view transitions, server islands. | @valencets/resultkit |
@valencets/db |
PostgreSQL query layer. Tagged template SQL, validated config, explicit SSL modes, Result-based error mapping, migration runner. | postgres, @valencets/resultkit, zod |
@valencets/cms |
Schema engine. collection() + field.* produces tables, validators, REST API, admin UI, auth, media. Rich text via Tiptap. |
tiptap, argon2, sharp, zod, @valencets/resultkit |
@valencets/graphql |
Auto-generated GraphQL schema + resolvers from CMS collections. | graphql, @valencets/resultkit |
@valencets/telemetry |
Beacon ingestion, event storage, daily summaries, consent-aware aggregation, retention cleanup. | postgres, @valencets/resultkit |
@valencets/reactive |
Zero-dependency signals package used by newer admin/login flows and available for app/runtime usage. | none |
@valencets/valence |
CLI + FSD scaffold + entity codegen + route types. | tsx, zod, @valencets/resultkit |
Core external runtime deps: 8. All MIT-licensed, all audited via Socket. Public-facing pages ship zero third-party JavaScript.
| Rule | Why |
|---|---|
| Complexity < 20 | Every function fits on one screen. |
Result<T, E> everywhere |
If it can fail, the type says so. Both branches handled. |
| 14kB critical shell | First paint in the first TCP round trip. |
| Pre-allocated ring buffer | Zero allocation in the telemetry hot path. |
| Zero third-party JS on public pages | Your site ships your code. Tiptap is admin-only. |
| 3k+ tests | Strict TypeScript, neostandard, API review, contract checks, and CI on every push. |
Valence is pre-1.0 and in active development. The schema engine, admin panel, REST API, GraphQL layer, telemetry pipeline, CLI, and Web Components are functional and tested. Recent work has focused on DB package hardening, stricter config/scaffold alignment, and tighter local-to-CI parity. Security hardening and API surface cleanup are still ongoing.
See the Architecture doc for a detailed overview of the framework design.
git clone https://github.com/valencets/valence.git
cd valence
pnpm install
pnpm build
pnpm testSee CONTRIBUTING.md for standards and the TDD workflow.
MIT