voltjs-framework
v1.0.0
Published
VoltJS - Lightning-fast, batteries-included, security-first JavaScript framework. Zero boilerplate, maximum power.
Maintainers
Readme
âš¡ VoltJS
The batteries-included, security-first JavaScript framework.
Zero boilerplate. Zero config. Everything you need — out of the box.
npx voltjs create my-app
cd my-app
npm install
npm run devWhy VoltJS?
| Problem | VoltJS Solution | |---------|----------------| | Express needs 20+ packages to be production-ready | Everything built-in — security, ORM, mail, PDF, Excel, SMS, caching, queues | | CSRF, XSS, CORS require manual setup | All security ON by default — zero-config protection | | Next.js / Nuxt are heavy and opinionated | Lightweight & flexible — use what you need | | Setting up auth takes hours | Auth in 2 lines — JWT, sessions, API keys, RBAC, 2FA | | Need separate packages for email, PDF, Excel | Built-in utilities — no extra dependencies | | File-based routing OR programmatic? | Both — choose your style |
Single Import, Everything Available
const {
Volt, Router, Auth, Mail, Excel, PDF, SMS,
Database, Model, Cache, Queue, Cron, Logger,
Validator, HttpClient, Storage, Hash, EventBus,
Component, Reactive, RestAPI, WebSocketServer, GraphQLHandler,
Form, Schema, _, Collection,
} = require('voltjs-framework');Table of Contents
- Quick Start
- Routing
- Security
- Database & ORM
- Authentication
- Validation
- SMS
- Excel Import/Export
- PDF Generation
- File Storage
- Caching
- Job Queues
- Scheduled Tasks (Cron)
- WebSockets
- GraphQL
- REST API Builder
- Reactive State
- Components
- Template Engine
- Form Handling
- Schema Validation (Zod)
- Collection Utilities (Lodash)
- classNames / clsx
- Logging
- HTTP Client
- CLI Commands
- Configuration
- Project Structure
Quick Start
Create a New Project
npx voltjs create my-app
cd my-app
npm install
npm run devMinimal App (2 files)
app.js:
const { Volt } = require('voltjs-framework');
const app = new Volt();
app.get('/', (req, res) => {
res.json({ message: 'Hello VoltJS! âš¡' });
});
app.listen(3000);That's it. CSRF, XSS protection, CORS, rate limiting, and security headers are all active.
What's Built In (No Extra Packages Needed)
| Category | Replaces | VoltJS Module |
|----------|----------|---------------|
| State Management | Redux, Zustand, MobX | Reactive.createStore() — signals, actions, undo/redo, persist |
| HTTP Client | Axios, Fetch wrappers | HttpClient — interceptors, retries, gzip |
| Data Fetching | SWR, React Query | HttpClient.swr() — stale-while-revalidate, dedup, polling |
| Routing | Express Router, Next.js | Router — file-based + programmatic, groups, params |
| Form Handling | React Hook Form, Formik | Form — dirty/touched, field errors, arrays, submit |
| Schema Validation | Zod, Yup, Joi | Schema — chainable types, transforms, coercion, unions |
| String Validation | Validator.js | Validator — 25+ rules, middleware, static checks |
| Utilities | Lodash, Underscore | _ — chunk, debounce, groupBy, merge, cloneDeep, 80+ utils |
| Date Utils | Moment.js, Day.js, date-fns | DateHelper — format, ago, add, diff, range |
| UUID | uuid, nanoid | Hash.uuid() — crypto.randomUUID |
| CSS Classes | classnames, clsx | _.classNames() — conditional class merging |
| Email | Nodemailer | Mail — raw SMTP, attachments, templates |
| PDF | PDFKit, jsPDF | PDF — raw PDF generation |
| Excel | ExcelJS, SheetJS | Excel — CSV/XLSX read/write |
| Caching | node-cache, ioredis | Cache — LRU, TTL, middleware |
| Job Queues | Bull, BullMQ | Queue — retries, priorities, concurrency |
Routing
Programmatic Routes
app.get('/users', listUsers);
app.post('/users', createUser);
app.get('/users/:id', showUser);
app.put('/users/:id', updateUser);
app.delete('/users/:id', deleteUser);
// Resource routes (auto CRUD)
app.resource('/api/posts', {
index: listPosts,
show: showPost,
store: createPost,
update: updatePost,
destroy: deletePost,
});
// Route groups
app.group('/admin', [authMiddleware], (group) => {
group.get('/dashboard', dashboard);
group.get('/settings', settings);
});File-Based Routing
pages/
├── index.js → GET /
├── about.js → GET /about
├── blog/
│ ├── index.js → GET /blog
│ └── [id].js → GET /blog/:id
api/
├── users.js → GET/POST /api/users
└── users/
└── [id].js → GET/PUT/DELETE /api/users/:idpages/about.js:
module.exports = {
get(req, res) {
res.render('about', { title: 'About Us' });
},
};Security
All protections are enabled by default. No setup required.
const { Volt } = require('voltjs-framework');
const app = new Volt();
// ✅ CSRF protection — active
// ✅ XSS sanitization — active
// ✅ CORS handling — active
// ✅ Rate limiting — active
// ✅ Security headers (helmet) — active
// ✅ Input sanitization — activeCustomize Security
// volt.config.js
module.exports = {
security: {
csrf: true,
cors: { origin: 'https://mysite.com', credentials: true },
rateLimit: { windowMs: 15 * 60 * 1000, max: 100 },
helmet: true,
},
};Manual Security Usage
const { CSRF, XSS, CORS, RateLimiter, Encryption } = require('voltjs-framework');
// Encrypt/decrypt data
const encrypted = Encryption.encrypt('sensitive data', 'secret-key');
const decrypted = Encryption.decrypt(encrypted, 'secret-key');
// Hash comparison (timing-safe)
Encryption.timingSafeCompare(hash1, hash2);
// Generate OTP
const otp = Encryption.generateOTP(6); // "482916"Database & ORM
Quick Setup (In-Memory — Zero Config)
const { Database, Model } = require('voltjs-framework');
const db = new Database(); // In-memory by default
await db.connect();Adapters
// SQLite
const db = new Database({ driver: 'sqlite', database: './app.db' });
// MySQL
const db = new Database({ driver: 'mysql', host: 'localhost', database: 'myapp', user: 'root' });
// PostgreSQL
const db = new Database({ driver: 'postgres', host: 'localhost', database: 'myapp', user: 'postgres' });Active Record ORM
class User extends Model {
static table = 'users';
static schema = {
name: { type: 'string', required: true, maxLength: 100 },
email: { type: 'string', required: true },
age: { type: 'number', min: 0 },
};
}
// CRUD
const user = await User.create({ name: 'Jane', email: '[email protected]' });
const users = await User.all();
const found = await User.find(1);
const filtered = await User.where({ age: 25 });
await User.updateById(1, { name: 'Jane Doe' });
await User.deleteById(1);
// Pagination
const page = await User.paginate(1, 20); // { data: [...], meta: { ... } }Fluent Query Builder
const { QueryBuilder } = require('voltjs-framework');
const results = await new QueryBuilder(db)
.table('users')
.select('name', 'email')
.where('age', '>', 18)
.whereLike('name', '%john%')
.orderBy('created_at', 'DESC')
.limit(10)
.get();Migrations
volt generate migration create_users_table
volt db:migrate
volt db:rollbackAuthentication
const { Auth } = require('voltjs-framework');
// JWT
const token = Auth.generateToken({ userId: 1 }, 'secret', '24h');
const payload = Auth.verifyToken(token, 'secret');
const { accessToken, refreshToken } = Auth.generateTokenPair({ userId: 1 }, 'secret');
// Password hashing
const hash = await Auth.hashPassword('mypassword');
const valid = await Auth.verifyPassword('mypassword', hash);
// Middleware
app.get('/protected', Auth.requireAuth('secret'), handler);
app.get('/admin', Auth.requireRole('admin'), adminHandler);
// Sessions
const sessionId = Auth.createSession({ userId: 1, role: 'admin' });
const session = Auth.getSession(sessionId);
// API Keys
const key = Auth.generateApiKey();
app.get('/api/data', Auth.requireApiKey(['key1', 'key2']), handler);
// 2FA (TOTP)
const { secret, uri } = Auth.generateTOTPSecret('MyApp', '[email protected]');
const isValid = Auth.verifyTOTP('123456', secret);
// RBAC
Auth.defineRole('editor', ['posts:read', 'posts:write', 'posts:delete']);
app.post('/posts', Auth.requirePermission('posts:write'), createPost);Validation
const { Validator } = require('voltjs-framework');
const result = Validator.validate(req.body, {
name: 'required|string|min:2|max:50',
email: 'required|email',
age: 'required|integer|min:18|max:120',
password: 'required|min:8|strongPassword',
website: 'url',
role: 'in:admin,user,editor',
phone: 'phone',
tags: 'array',
});
if (!result.valid) {
console.log(result.errors);
// { email: ['email must be a valid email'], age: ['age must be at least 18'] }
}
// As middleware
app.post('/register', Validator.body({
name: 'required|string|min:2',
email: 'required|email',
password: 'required|min:8|strongPassword',
}), registerHandler);
// Individual validators
Validator.isEmail('[email protected]'); // true
Validator.isURL('https://example.com'); // true
Validator.isCreditCard('4111111111111111'); // true
Validator.isStrongPassword('Abc123!@#'); // true
Validator.isUUID('550e8400-e29b-41d4-a716-446655440000'); // trueconst { Mail } = require('voltjs-framework');
const mail = new Mail({
host: 'smtp.gmail.com',
port: 587,
user: '[email protected]',
pass: 'app-password',
});
// Send email
await mail.send({
to: '[email protected]',
subject: 'Welcome!',
html: '<h1>Hello {{name}}</h1>',
data: { name: 'John' },
});
// With attachments
await mail.send({
to: '[email protected]',
subject: 'Report',
text: 'Please find attached.',
attachments: [
{ filename: 'report.pdf', content: pdfBuffer },
],
});
// Quick send (static)
await Mail.quickSend(config, { to, subject, html });SMS
const { SMS } = require('voltjs-framework');
const sms = new SMS({
provider: 'twilio',
accountSid: process.env.TWILIO_SID,
authToken: process.env.TWILIO_TOKEN,
from: '+1234567890',
});
await sms.send('+1987654321', 'Hello from VoltJS!');
// Send OTP
await sms.sendOTP('+1987654321', '5829');
// Bulk send
await sms.sendBulk(['+111111', '+222222'], 'Announcement!');Excel Import/Export
const { Excel } = require('voltjs-framework');
// Export to CSV
Excel.writeCSV('users.csv', [
{ name: 'John', email: '[email protected]', age: 30 },
{ name: 'Jane', email: '[email protected]', age: 25 },
]);
// Import from CSV
const data = Excel.readCSV('users.csv');
// Export to XLSX (real Excel file, zero dependencies!)
Excel.writeXLSX('report.xlsx', data, { sheetName: 'Users' });
// Import from XLSX
const xlsxData = Excel.readXLSX('report.xlsx');
// JSON import/export
Excel.writeJSON('data.json', data);
const jsonData = Excel.readJSON('data.json');PDF Generation
const { PDF } = require('voltjs-framework');
const pdf = new PDF();
pdf.addPage();
pdf.setFont('Helvetica', 24);
pdf.text(50, 50, 'Hello VoltJS!');
pdf.setFont('Helvetica', 12);
pdf.paragraph(50, 100, 'This PDF was generated from scratch with zero dependencies.', 500);
// Tables
pdf.table(50, 200, {
headers: ['Name', 'Email', 'Role'],
rows: [
['John Doe', '[email protected]', 'Admin'],
['Jane Smith', '[email protected]', 'User'],
],
columnWidths: [150, 200, 100],
});
pdf.save('output.pdf');
// Quick report from data
PDF.fromData('Report Title', columns, rows).save('report.pdf');
// Generate invoice
PDF.invoice({ company, customer, items, tax }).save('invoice.pdf');File Storage
const { Storage } = require('voltjs-framework');
const storage = new Storage({ root: './uploads' });
await storage.put('avatars/user1.png', imageBuffer);
const file = await storage.get('avatars/user1.png');
const exists = await storage.exists('avatars/user1.png');
await storage.delete('avatars/user1.png');
const url = storage.url('avatars/user1.png');
// S3-compatible storage
const s3 = new Storage({
driver: 's3',
bucket: 'my-bucket',
region: 'us-east-1',
accessKey: process.env.S3_ACCESS_KEY,
secretKey: process.env.S3_SECRET_KEY,
});
// Upload middleware
app.post('/upload', Storage.upload({
dest: 'uploads',
maxSize: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/png', 'image/jpeg'],
}), handler);Caching
const { Cache } = require('voltjs-framework');
const cache = new Cache({ maxSize: 10000, defaultTTL: 300 });
cache.set('user:1', userData, 60); // 60 second TTL
const user = cache.get('user:1');
// Get-or-set pattern
const data = await cache.getOrSet('expensive-query', async () => {
return await db.query('SELECT ...');
}, 120);
// Response caching middleware
app.get('/api/data', Cache.middleware(60), handler);
// Stats
cache.stats(); // { size: 42, hits: 150, misses: 12, hitRate: '92.6%' }Job Queues
const { Queue } = require('voltjs-framework');
const emailQueue = new Queue('emails', { concurrency: 3, retries: 3 });
emailQueue.process(async (job) => {
await sendEmail(job.data);
});
emailQueue.add({ to: '[email protected]', subject: 'Hello' });
emailQueue.add(urgentJob, { priority: 'high', delay: 5000 });
emailQueue.on('completed', (job) => console.log(`Done: ${job.id}`));
emailQueue.on('failed', (job, err) => console.error(`Failed: ${err.message}`));Scheduled Tasks (Cron)
const { Cron } = require('voltjs-framework');
const cron = new Cron();
cron.schedule('cleanup', '0 * * * *', cleanupOldFiles); // Every hour
cron.schedule('report', '0 9 * * 1', sendWeeklyReport); // Monday 9am
cron.schedule('backup', '0 2 * * *', backupDatabase); // Daily 2am
// Convenience methods
cron.everyMinute('health-check', checkHealth);
cron.daily('cleanup', cleanupTask);
cron.weekly('report', generateReport);
cron.start();WebSockets
const { Volt, WebSocketServer } = require('voltjs-framework');
const app = new Volt();
const wss = new WebSocketServer(app, { path: '/ws' });
wss.on('connection', (client) => {
console.log(`Client connected: ${client.id}`);
client.join('lobby');
client.on('chat', (data) => {
wss.to('lobby').emit('chat', {
user: client.id,
message: data.message,
});
});
});
wss.requireAuth(async (req, client) => {
const token = req.headers['authorization'];
return Auth.verifyToken(token, 'secret');
});
app.listen(3000);GraphQL
const { GraphQLHandler } = require('voltjs-framework');
const gql = new GraphQLHandler();
gql.type('User', {
id: 'ID!',
name: 'String!',
email: 'String',
});
gql.query('users', {}, async () => await User.all());
gql.query('user', { id: 'ID!' }, async ({ id }) => await User.find(id));
gql.mutation('createUser', { name: 'String!', email: 'String!' }, async (args) => {
return await User.create(args);
});
app.post('/graphql', gql.middleware());REST API Builder
const { RestAPI } = require('voltjs-framework');
const api = new RestAPI(app, { prefix: '/api/v1' });
api.resource('users', {
async index(req, res) { return await User.all(); },
async show(req, res) { return await User.find(req.params.id); },
async store(req, res) { return await User.create(req.body); },
async update(req, res) { return await User.updateById(req.params.id, req.body); },
async destroy(req, res) { await User.deleteById(req.params.id); res.noContent(); },
});
// Versioned API groups
api.version(2, (v2) => {
v2.get('/status', (req, res) => res.json({ version: 2, status: 'ok' }));
});Reactive State
const { Reactive } = require('voltjs-framework');
const count = Reactive.signal(0);
const doubled = Reactive.computed(() => count.value * 2);
Reactive.effect(() => {
console.log(`Count: ${count.value}, Doubled: ${doubled.value}`);
});
count.value = 5; // Logs: "Count: 5, Doubled: 10"
// Reactive store
const store = Reactive.store({
user: null,
theme: 'dark',
count: 0,
});
store.$watch('count', (val) => console.log('Count changed:', val));
store.count = 42;
// Batch updates
Reactive.batch(() => {
store.count = 1;
store.theme = 'light';
}); // Single re-renderAdvanced Store (Redux-like Actions, Undo/Redo, Persist)
const counter = Reactive.createStore({
state: { count: 0, todos: [] },
actions: {
increment(state) { state.count++; },
add(state, amount) { state.count += amount; },
addTodo(state, text) { state.todos = [...state.todos, text]; },
},
middleware: [Reactive.loggerMiddleware],
persist: { storage: 'file', path: './.store.json' },
history: true,
});
counter.dispatch('increment');
counter.dispatch('add', 5);
// Memoized selectors
const total = counter.select(s => s.count);
console.log(total.value); // 6
// Undo / Redo
counter.$undo();
console.log(counter.count); // 1
counter.$redo();
console.log(counter.count); // 6
// Subscribe to all changes
counter.$subscribe((key, value, snapshot) => {
console.log(`${key} changed to`, value);
});Components
const { Component } = require('voltjs-framework');
class Card extends Component {
setup() {
this.state = { likes: 0 };
}
render() {
return `
<div class="${this.$class({ card: true, featured: this.props.featured })}">
<h3>${this.$escape(this.props.title)}</h3>
<p>${this.$escape(this.props.body)}</p>
<span>Likes: ${this.state.likes}</span>
</div>
`;
}
}
// Usage in route
app.get('/cards', (req, res) => {
const html = Component.render(Card, { title: 'Hello', body: 'World' });
res.html(html);
});Template Engine
VoltJS includes a Mustache-like template engine with layouts, partials, loops, and conditionals.
<!-- views/layouts/main.volt -->
<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
{> header}
<main>{#slot content}</main>
{> footer}
</body>
</html>
<!-- views/index.volt -->
{#layout layouts/main}
{#block content}
<h1>{{ title }}</h1>
{#if user}
<p>Welcome, {{ user.name }}!</p>
{#else}
<p>Please log in.</p>
{/if}
<ul>
{#each items as item}
<li>{{ item.name }} - ${{ item.price }}</li>
{/each}
</ul>
{/block}app.get('/', (req, res) => {
res.render('index', { title: 'Home', user, items });
});Form Handling
Built-in form state management — like React Hook Form with dirty/touched tracking, field-level errors, array fields, watchers, and submission handling.
const { Form } = require('voltjs-framework');
const form = new Form({
defaults: { name: '', email: '', tags: [] },
rules: {
name: 'required|string|min:2',
email: 'required|email',
},
validateOn: 'change', // 'change' | 'blur' | 'submit'
onSubmit: async (data) => await User.create(data),
});
form.set('name', 'John');
form.set('email', '[email protected]');
// State tracking
form.isDirty; // true
form.isFieldDirty('name'); // true
form.isFieldTouched('name'); // false
form.touch('name'); // mark as touched
form.dirtyValues; // { name: 'John', email: '[email protected]' }
// Array fields
form.append('tags', 'javascript');
form.append('tags', 'nodejs');
form.remove('tags', 0);
form.move('tags', 0, 1);
// Nested fields (dot notation)
form.set('address.city', 'NYC');
form.get('address.city'); // 'NYC'
// Watch field changes
form.watch('email', (newVal, oldVal) => console.log('Email changed'));
// Submit
const result = await form.submit();
// { success: true, data: { ... } } or { success: false, errors: { ... } }
// Reset
form.reset();
// As middleware
app.post('/register', Form.handle({
rules: { name: 'required', email: 'required|email' },
onSubmit: (data) => User.create(data),
}), (req, res) => {
res.json(req.formResult);
});Schema Validation (Zod)
Type-safe, chainable schema builder — like Zod/Yup with transforms, coercion, nested objects, arrays, unions, and enums.
const { Schema } = require('voltjs-framework');
const userSchema = Schema.object({
name: Schema.string().min(2).max(50).trim().required(),
email: Schema.string().email().toLowerCase().required(),
age: Schema.number().int().min(18).max(120).optional(),
role: Schema.enum(['admin', 'user', 'editor']).default('user'),
tags: Schema.array(Schema.string()).min(1).unique(),
website: Schema.string().url().optional(),
address: Schema.object({
street: Schema.string(),
city: Schema.string().required(),
zip: Schema.string().regex(/^\d{5}$/),
}).optional(),
});
// Validate (returns result)
const result = userSchema.validate(data);
if (!result.valid) console.log(result.errors);
// Parse (throws on invalid)
const parsed = userSchema.parse(data);
// Safe parse (never throws)
const safe = userSchema.safeParse(data);
// Schema composition
const updateSchema = userSchema.partial(); // All fields optional
const loginSchema = userSchema.pick(['email']); // Only email
const publicSchema = userSchema.omit(['age']); // Remove age
// Coercion (auto-convert types)
const configSchema = Schema.object({
port: Schema.number().coerce().int().min(0).max(65535),
debug: Schema.boolean().coerce(),
});
configSchema.parse({ port: '3000', debug: 'true' });
// { port: 3000, debug: true }
// Unions, literals, tuples
const statusSchema = Schema.union([
Schema.literal('active'),
Schema.literal('inactive'),
]);
const pointSchema = Schema.tuple([
Schema.number(), Schema.number(),
]);
// Custom refinements
const passwordSchema = Schema.string()
.min(8)
.refine(v => /[A-Z]/.test(v), 'Must have uppercase')
.refine(v => /\d/.test(v), 'Must have a number');
// Record (key-value maps)
const envSchema = Schema.record(Schema.string(), Schema.string());
// Recursive schemas
const categorySchema = Schema.object({
name: Schema.string().required(),
children: Schema.lazy(() => Schema.array(categorySchema)),
});Collection Utilities (Lodash)
Full Lodash-equivalent utilities — arrays, objects, functions — zero dependencies.
const { _ } = require('voltjs-framework');
// Arrays
_.chunk([1,2,3,4,5], 2); // [[1,2],[3,4],[5]]
_.compact([0, 1, false, 2, '']); // [1, 2]
_.flatten([[1,[2]],[3]]); // [1,[2],3]
_.flattenDeep([[1,[2,[3]]]]); // [1,2,3]
_.uniq([1, 2, 2, 3]); // [1, 2, 3]
_.uniqBy(users, 'email'); // Unique by email
_.intersection([1,2], [2,3]); // [2]
_.difference([1,2,3], [2,3]); // [1]
_.union([1,2], [2,3]); // [1,2,3]
_.zip([1,2], ['a','b']); // [[1,'a'],[2,'b']]
// Grouping & sorting
_.groupBy(users, 'role'); // { admin: [...], user: [...] }
_.keyBy(users, 'id'); // { 1: {...}, 2: {...} }
_.sortBy(users, 'name'); // Sorted by name
_.orderBy(users, ['age','name'], ['desc','asc']);
_.countBy(users, 'role'); // { admin: 2, user: 5 }
_.partition(nums, n => n > 0); // [[positives], [negatives]]
// Aggregation
_.sum([1, 2, 3]); // 6
_.sumBy(items, 'price'); // Total price
_.mean([1, 2, 3, 4]); // 2.5
_.minBy(users, 'age'); // Youngest user
_.maxBy(users, 'age'); // Oldest user
// Random
_.sample([1, 2, 3]); // Random element
_.sampleSize([1,2,3,4], 2); // 2 random elements
_.shuffle([1, 2, 3, 4, 5]); // Shuffled
_.range(0, 10, 2); // [0, 2, 4, 6, 8]
_.times(5, i => i * 2); // [0, 2, 4, 6, 8]
// Objects
_.get(obj, 'a.b[0].c', 'default'); // Deep path access
_.set(obj, 'a.b.c', 42); // Deep path set
_.has(obj, 'a.b.c'); // true/false
_.pick(obj, ['name', 'email']); // { name, email }
_.omit(obj, ['password']); // Without password
_.merge(defaults, overrides); // Deep merge
_.cloneDeep(obj); // Deep clone
_.isEqual(objA, objB); // Deep equality
_.isEmpty({}); // true
_.mapValues(obj, v => v * 2); // Transform values
_.mapKeys(obj, k => k.toUpperCase());
_.invert({ a: 1, b: 2 }); // { 1: 'a', 2: 'b' }
_.freezeDeep(obj); // Deep freeze (immutable)
// Functions
const save = _.debounce(saveData, 300); // Debounce
const scroll = _.throttle(onScroll, 100); // Throttle
const loadOnce = _.once(loadConfig); // Execute only once
const factorial = _.memoize(calcFactorial);// Memoize results
_.curry(fn); // Curry
_.pipe(fn1, fn2, fn3)(input); // Pipe (left to right)
_.compose(fn3, fn2, fn1)(input); // Compose (right to left)
await _.retry(fetchData, { attempts: 3 }); // Retry with backoff
await _.delay(fn, 1000); // Delayed execution
await _.sleep(500); // Sleep/wait
// Type checks
_.isString('hello'); // true
_.isNumber(42); // true
_.isArray([]); // true
_.isObject({}); // true
_.isNil(null); // true
_.isPlainObject({}); // true
_.isEmpty([]); // true
// Misc
_.toQueryString({ page: 1, q: 'hello' }); // 'page=1&q=hello'
_.parseQueryString('page=1&q=hello'); // { page: '1', q: 'hello' }
_.tryParse('{"a":1}'); // { a: 1 }
_.uniqueId('user_'); // 'user_1'classNames / clsx
const { _ } = require('voltjs-framework');
_.classNames('btn', { active: true, disabled: false }, 'primary');
// => 'btn active primary'
_.classNames('flex', condition && 'hidden', ['p-4', { 'bg-red': error }]);
// => 'flex hidden p-4 bg-red' (if condition and error are truthy)
_.clsx('text-lg', { bold: isBold }); // Alias for classNamesLogging
const { Logger } = require('voltjs-framework');
const log = new Logger({ level: 'debug', file: 'logs/app.log' });
log.info('Server started', { port: 3000 });
log.debug('Query executed', { sql: '...', duration: '12ms' });
log.warn('Deprecated API used');
log.error('Connection failed', { error: err.message });
// Request logging middleware
app.use(Logger.requestLogger());
// Child loggers
const dbLog = log.child('database');
dbLog.info('Connected'); // [database] Connected
// Timing
const timer = log.time('query');
await db.query('...');
timer.end(); // "query completed in 12.34ms"HTTP Client
const { HttpClient } = require('voltjs-framework');
// Quick usage
const response = await HttpClient.get('https://api.example.com/users');
console.log(response.data);
// Instance with defaults
const api = new HttpClient({
baseURL: 'https://api.example.com',
timeout: 10000,
retries: 2,
});
api.setBearerToken('my-token');
const users = await api.get('/users');
const created = await api.post('/users', { name: 'John' });
const updated = await api.put('/users/1', { name: 'Jane' });
await api.delete('/users/1');
// Download files
await api.download('https://example.com/file.pdf', './downloads/file.pdf');
// SWR (stale-while-revalidate) — like SWR/React Query
const fetcher = HttpClient.swr({ ttl: 30, revalidate: 120 });
const data = await fetcher.get('/api/users'); // Cached + background refresh
fetcher.mutate('/api/users', newData); // Optimistic update
fetcher.invalidate('/api/users'); // Force refetch
// Polling
const poller = HttpClient.poll('https://api.example.com/status', {
interval: 5000,
onData: (data) => console.log(data),
until: (data) => data.status === 'complete',
});
poller.stop();
// Concurrent requests
const [users, posts] = await HttpClient.all([
HttpClient.get('/api/users'),
HttpClient.get('/api/posts'),
]);
// Abortable requests
const { promise, abort } = HttpClient.abortable('https://api.example.com/data');
setTimeout(() => abort(), 5000);
const result = await promise;CLI Commands
volt create <name> # Create a new project
volt dev # Start dev server with hot reload
volt build # Build for production
volt start # Start production server
volt generate page <name> # Generate a page + view
volt generate api <name> # Generate an API route
volt generate component <name> # Generate a component
volt generate model <name> # Generate a model
volt generate middleware <name> # Generate middleware
volt generate migration <name> # Generate a migration
volt generate seeder <name> # Generate a seeder
volt db:migrate # Run migrations
volt db:rollback # Rollback last migration
volt db:seed # Run seeders
volt routes # List all routes
volt lint # Lint project
volt test # Run testsConfiguration
volt.config.js:
module.exports = {
port: 3000,
security: {
csrf: true,
cors: { origin: '*', credentials: true },
rateLimit: { windowMs: 900000, max: 100 },
helmet: true,
},
database: {
driver: 'sqlite', // 'memory' | 'sqlite' | 'mysql' | 'postgres'
database: './app.db',
},
views: {
dir: './views',
engine: 'volt',
},
mail: {
host: process.env.MAIL_HOST,
port: 587,
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASS,
},
logging: {
level: 'info',
file: './logs/app.log',
},
};All settings can be overridden via environment variables:
PORT,NODE_ENVDB_DRIVER,DB_HOST,DB_PORT,DB_DATABASE,DB_USER,DB_PASSWORDMAIL_HOST,MAIL_PORT,MAIL_USER,MAIL_PASSAPP_SECRET
Project Structure
my-app/
├── app.js # Application entry point
├── volt.config.js # Configuration
├── package.json
├── .env # Environment variables
├── pages/ # File-based routes (auto-discovered)
│ ├── index.js # → GET /
│ └── about.js # → GET /about
├── api/ # API routes (auto-discovered)
│ └── users.js # → /api/users
├── views/ # Templates
│ ├── layouts/
│ │ └── main.volt
│ ├── partials/
│ │ ├── header.volt
│ │ └── footer.volt
│ └── index.volt
├── components/ # Reusable components
├── models/ # Database models
├── middleware/ # Custom middleware
├── public/ # Static assets (served automatically)
│ ├── css/
│ ├── js/
│ └── images/
├── database/
│ ├── migrations/
│ └── seeders/
├── storage/ # File uploads
├── tests/ # Test files
└── logs/ # Log filesDesign Principles
- Zero Config — Works out of the box with sensible defaults
- Security First — All protections enabled by default
- Batteries Included — No hunting for packages
- Minimal Boilerplate — 2 files to start a full app
- Progressive — Use only what you need
- Zero External Dependencies — Only
wsfor WebSocket support; everything else uses native Node.js
Requirements
- Node.js >= 18.0.0
Optional Dependencies
| Package | For |
|---------|-----|
| ws | WebSocket support |
| better-sqlite3 | SQLite database |
| mysql2 | MySQL database |
| pg | PostgreSQL database |
License
MIT
Built with âš¡ by the VoltJS team.
