Drizzle ORM-first semantic layer with Cube.js compatibility
Transform your Drizzle schema into a powerful, type-safe analytics platform with SQL injection protection and full TypeScript support.
π Documentation π Try the Sandbox
π SQL Injection Proof - All queries use Drizzle's parameterized SQL
π‘οΈ Type Safe - Full TypeScript inference from your database schema
β‘ Performance - Prepared statements and query optimization
π§© Cube.js Compatible - Works with existing Cube.js React components
π― Zero Config - Infer cube definitions from your Drizzle schema
npm install drizzle-cube drizzle-orm// schema.ts
import { pgTable, text, integer, boolean } from 'drizzle-orm/pg-core'
export const employees = pgTable('employees', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
email: text('email'),
active: boolean('active').default(true),
department: integer('department'),
organisation: integer('organisation').notNull()
})
export const departments = pgTable('departments', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
organisation: integer('organisation').notNull()
})
export const schema = { employees, departments }// cubes.ts
import { defineCube } from 'drizzle-cube/server'
import { eq } from 'drizzle-orm'
import { schema } from './schema'
export const employeesCube = defineCube('Employees', {
sql: (ctx) => ({
from: schema.employees,
where: eq(schema.employees.organisation, ctx.securityContext.organisationId)
}),
dimensions: {
name: {
name: 'name',
title: 'Employee Name',
type: 'string',
sql: schema.employees.name
},
email: {
name: 'email',
title: 'Email',
type: 'string',
sql: schema.employees.email
}
},
measures: {
count: {
name: 'count',
title: 'Total Employees',
type: 'count',
sql: schema.employees.id
}
}
})// server.ts (Hono example)
import { Hono } from 'hono'
import { drizzle } from 'drizzle-orm/postgres-js'
import { createCubeApp } from 'drizzle-cube/adapters/hono'
import postgres from 'postgres'
import { schema } from './schema'
import { employeesCube } from './cubes'
const db = drizzle(postgres(process.env.DATABASE_URL!), { schema })
const app = createCubeApp({
cubes: [employeesCube],
drizzle: db,
schema,
getSecurityContext: async () => ({
organisationId: 1 // Your auth logic here
})
})
export default app// Use built-in React components
import { QueryBuilder, AnalyticsDashboard } from 'drizzle-cube/client'
function App() {
return (
<div>
<QueryBuilder apiUrl="/cubejs-api/v1" />
<AnalyticsDashboard
config={dashboardConfig}
baseUrl="/cubejs-api/v1"
/>
</div>
)
}π SQL Injection Proof - All queries use Drizzle's parameterized SQL π‘οΈ Type Safe - Full TypeScript inference from your database schema β‘ Performance - Prepared statements and query optimization π§© Cube.js Compatible - Works with existing Cube.js React components π― Zero Config - Infer cube definitions from your Drizzle schema π¨ Themeable - Built-in light/dark themes with CSS variables
β Multiple Database Types - PostgreSQL, MySQL β Framework Adapters - Hono, Express, Fastify, Next.js β Full Type Safety - Complete TypeScript inference β All SQL Features - Joins, CTEs, subqueries, window functions β Cube.js Compatibility - Drop-in replacement for existing apps β Scalable Theming - Built-in themes (light/dark/neon) with semantic CSS variables
Drizzle Cube features a scalable semantic theming system with three built-in themes. All components automatically adapt using CSS variables - no component changes needed when adding new themes!
π Light - Clean white backgrounds with blue accents π Dark - Slate grays with lighter blue highlights β‘ Neon - Bold fluorescent colors with deep purple backgrounds
import { getTheme, setTheme, watchThemeChanges } from 'drizzle-cube/client'
// Set a theme programmatically
setTheme('neon') // 'light' | 'dark' | 'neon'
// Get current theme
const currentTheme = getTheme()
// Watch for theme changes
watchThemeChanges((theme) => {
console.log('Theme changed:', theme)
})Create your own theme by defining CSS variables - zero component changes required:
[data-theme="ocean"] {
/* Surface colors */
--dc-surface: #001f3f;
--dc-surface-secondary: #002b5c;
--dc-card-bg: #003366;
/* Text colors */
--dc-text: #e6f7ff;
--dc-text-secondary: #b3d9ff;
/* Primary/accent colors */
--dc-primary: #39cccc;
--dc-border: #004d66;
/* ... other semantic variables */
}Then update your theme toggle to include the new theme:
setTheme('ocean') // It just works! β¨- π Full Documentation - Complete guides and API reference
- π Try the Sandbox - Working example version to experiment with
npm run dev- Hono Example - Full-featured dashboard with Cloudflare Workers support
- Express Example - Simple Express.js server with React dashboard
- Fastify Example - High-performance Fastify server with React client
- Next.js Example - Full-stack Next.js app with API routes
We welcome contributions! Please see our Contributing Guide.
- π Pre-aggregations - Materialized view support
- π Real-time Updates - WebSocket support
- π Query Caching - Redis integration
MIT Β© Clifton Cunningham
Built with β€οΈ for the Drizzle ORM community