
Product
Rust Support in Socket Is Now Generally Available
Socket’s Rust and Cargo support is now generally available, providing dependency analysis and supply chain visibility for Rust projects.
stackpress
Advanced tools
Stackpress is a content management framework. It combines several open source projects maintained by the Stackpress Team.
The goal of Stackpress is to build robust apps in days, not months.
Unlike other frameworks, we have chosen the following philosophies.
import { server } from 'stackpress/http'
const app = server()
app.get('/', (req, res) => {
const name = req.data.path('name', 'guest')
res.setBody('text/plain', `Hello ${name}`)
})
app.create().listen(3000, () => {
console.log('Server is running on port 3000')
})
See Example for use case.
Stackpress uses several routers for callbacks, lazy imports and React templates. You can access each router like the following.
//action routing
app.action.get('/home', (req, res, ctx) => {});
//import routing
app.import.get('/home', () => import('./pages/home'));
//view routing (react)
app.view.get('/home', '@/views/home');
Like other server frameworks, the following route methods are available.
//common methods
app.connect('/home', action)
app.delete('/home', action)
app.get('/home', action)
app.head('/home', action)
app.options('/home', action)
app.patch('/home', action)
app.post('/home', action)
app.put('/home', action)
app.trace('/home', action)
//any method
app.all('/home', action)
//custom method
app.route('get', '/home')
You can let Stackpress infer your action implementation.
//action callback
app.get('/home', (req, res, ctx) => {});
//lazy import action
app.get('/home', () => import('./pages/home'));
//react template
app.get('/home', '@/views/home');
You can prioritize routing in the following way where the highest number calls first.
//first
app.get('/home', action, 100);
//second
app.get('/home', action);
//third
app.get('/home', action);
//fourth
app.get('/home', action, -100);
Routing is built on top of events, a necessity to event driven design.
app.on('email-send', logInDatabase)
app.on('email-send', smtpQueue)
app.on('email-send', updateDatabase)
Like routing, you can use action, imports and views.
//action callback
app.action.on('email-send', logInDatabase)
//use a separate file
app.import.on('email-send', () => import('/event/smtp-queue'))
//set the response view
app.view.on('email-send', '@/views/email/success')
A minimal database setup would look like the following.
import path from 'node:path'
import { PGlite } from '@electric-sql/pglite'
import { connect } from 'stackpress/pglite'
const db = await connect(async () => {
return new PGlite(path.resolve(cwd, 'database'))
})
app.register('database', db);
Stackpress has support for the following SQL packages.
mysql2pgpglitebetter-sqlite3No matter the SQL package, the query builder is exactly the same. See the following example.
const products = await db.select('*').from('products').where('price > %s', 100)
You can do a raw query like this as well.
const users = await db.query('SELECT * from users')
And you can do transactions like this.
await db.transaction(async () => {
await db.update('users').set({ age: 100 }).where('age > %s', 100)
})
The following is an example of a basic plugin you can create in your
project or use from a Stackpress project in node_modules.
//plugin.ts
import type { Server } from 'stackpress/server'
export default function MyPlugin(app: Server) {
//start plugging...
app.on('email-send', logInDatabase)
app.get('/signin', () => import('/page/signin'))
}
While developing a plugin, you can get the project configuration like this.
export default function MyPlugin(app: Server) {
//get all the config
const config = app.config()
//traverse the config
const cwd = app.config<string>('server', 'cwd')
//use dot pathing (default production)
const mode = app.config.path<string>('server.mode', 'production')
}
You can register your plugin so other plugins can access like this.
export default function MyPlugin(app: Server) {
app.register('my-plugin', { foo: 'bar' })
}
You can add plugins by manually importing them xor using package.json.
{
"name": "my-project",
"plugins": [ "./plugin", "stackpress" ],
"dependencies": {...}
}
To load (initialize) plugins you just need to run this code.
await app.bootstrap();
Then you can access plugins in your project like this.
const myPlugin = app.plugin('my-plugin')
//or
const myPlugin2 = app.plugin<{ foo: string }>('my-plugin')
To generate an admin you need to first create a schema.idea file in
the root of your project.
model User @label("User" "Users") @template("{{name}}") @icon("user") {
id String @label("ID")
@id @default("cuid()")
@list.overflow({ length 10 hellip true })
name String @label("Name")
@searchable
@field.text
@is.required
@list.text @view.text
}
Next emit emit following events.
await app.emit('config')
await app.emit('listen')
await app.emit('route')
Next export a const config in your project root with the following configuration.
export const config = {
client: {
//used by `stackpress/client` to `import()`
//the generated client code to memory
module: '.client',
//where to store the generated client code
build: path.join(cwd, 'node_modules', '.client'),
//what tsconfig file to base the typescript compiler on
tsconfig: path.join(cwd, 'tsconfig.json')
}
}
Then in terminal you can run the following.
$ npx stackpress index generate
This will generate a .client folder in node_modules. You can check
the admin by visiting http://localhost:3000/admin/user/search. You can
also access the ORM like the following.
import type { ClientPlugin } from 'stackpress'
const client = app.plugin<ClientPlugin>('client')
const user = await client.model.user.create({ name: 'John Doe' })
New events will be available as well.
import type { User } from '.client'
await app.resolve<User>('user-create', { name: 'John Doe' })
To use the default authentication, you need to add an auth configuration.
app.config.set('auth', {
//base route for signin, signout, signup pages
base: '/auth',
//default roles for new users
roles: [ 'USER' ],
//allow signin with username
username: true,
//allow signin with email address
email: true,
//allow signin with phone number
phone: true
})
Next you need to import the stackpress.idea file to your main
schema.idea.
use "stackpress/stackpress.idea"
//your models here...
Lastly run the following in terminal.
$ npx stackpress transform
$ npx stackpress push
When you add a session configuration, your project will deny access to
all pages (blacklist by default). You can open/configure route access
by roles using just the configuration.
app.config.set('session', {
//name of the session cookie
key: 'session',
//used to generate the session id
//also used to encrypt/decrypt data
//in the database
seed: 'ABC123',
access: {
//role: permissions
GUEST: [
//dev routes
{ method: 'ALL', route: '/@vite/client' },
{ method: 'ALL', route: '/@react-refresh' },
{ method: 'ALL', route: '/@fs/**' },
{ method: 'ALL', route: '/node_modules/**' },
{ method: 'ALL', route: '/__uno.css' },
{ method: 'ALL', route: '/plugins/**' },
{ method: 'ALL', route: '/react.svg' },
//public routes
{ method: 'GET', route: '/assets/**' },
{ method: 'GET', route: '/client/**' },
{ method: 'GET', route: '/images/**' },
{ method: 'GET', route: '/styles/**' },
{ method: 'GET', route: '/favicon.ico' },
{ method: 'GET', route: '/favicon.png' },
//page routes
{ method: 'GET', route: '/' },
{ method: 'ALL', route: '/auth/**' },
{ method: 'ALL', route: '/admin/**' },
{ method: 'ALL', route: '/api/**' }
]
}
})
By default everyone is a GUEST and other role names are arbitrary.
FAQs
Incept is a content management framework.
The npm package stackpress receives a total of 37 weekly downloads. As such, stackpress popularity was classified as not popular.
We found that stackpress demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket’s Rust and Cargo support is now generally available, providing dependency analysis and supply chain visibility for Rust projects.

Security News
Chrome 144 introduces the Temporal API, a modern approach to date and time handling designed to fix long-standing issues with JavaScript’s Date object.

Research
Five coordinated Chrome extensions enable session hijacking and block security controls across enterprise HR and ERP platforms.