
Security News
Django Joins curl in Pushing Back on AI Slop Security Reports
Django has updated its security policies to reject AI-generated vulnerability reports that include fabricated or unverifiable content.
m3-stack is a library with a set of tools and utilities to build, bundle and deploy web apps with react and backend with nodejs.
m3-stack is a library with a set of tools and utilities to build, bundle and deploy web apps with react and backend with nodejs.
It provides great defaults for creating a new app, bundling backend and frontend code, deploying to providers like Vercel. It also provides many importable modules to help you build your app faster.
drizzle-orm
and drizzle-kit
better-auth
vite
with react, typescript and tailwindcssPGLite
for instant local developmentI started this project recently, but in the process I've learnt a lot (more than what already knew) about build tools, cjs, esm, frameworks and more.
It is not my first time trying to build a stack, a useful library or a framework. It won't be the last.
This stack is not a framework like NextJS. It is a set of tools and utilities to help you build a web app with react. This stack can also be used as backend only, or frontend only.
NextJS is a great framework, but it is not the only way to build a web app. This stack is a different approach to building a web app. NextJS has some limitations.
NextJS is very limited in the control you can have over the backend. You can't control how your server starts or how it listens to requests. You can't use websockets. NextJS middleware is very limited. You also can't control how scripts, code or stuff is loaded into the client.
NextJS with app-router requires you to hit the server for every route change. This makes your app inevitably slower. You can't force a route to be client only (even if root component is marker as 'use client'). You don't have control over routing at all.
There are many use cases when you want client side routing. Specially if you want your app to be more responsive and with a native feeling. If your app needs to run offline it is much easier to cache a single bundle and use client side routing than to cache every possible page with nextjs.
A single frontend script and a single backend entrypoint it is much simpler than a a complex model of server and client components, server and client layouts and all the complex stuff of frameworks like NextJS.
To be fair, NextJS isn't as bad to host. But, still it has its limitations and complexities to self host. With a simple backend and frontend app it is as easy to start the server and serve static files. You can still host a m3-stack app with Vercel or Netlify and get the benefits of serverless/edge and static files CDN.
NextJS is unarguably more expensive to host than a simple nodejs server. In nextjs the server needs to process every page request. And it get worse if you need to server render a lot of big react pages. With a SPA you only process backend requests for api which in many cases is cached by the client (for example when using react-query)
A SPA is a better fit for local first apps. Having more control over client and backend code allows you to build a better local experience.
NextJS is great for many use cases. It is a great framework for building a web app with server side rendering. For blog, news, or any type of public static content it is a great choice. It has also faster first load times and a lot of cool features like image optimization, static site generation, incremental static regeneration, etc.
NextJS has definitely better SEO and performance for public content. You can also build super complex giant apps and probably achieve most or even all of the things you can do with a SPA. If you choose to use NextJS (or an alternative) you will be totally fine, and even much better in many cases.
THIS IS A WORK IN PROGRESS
Minimal project structure:
index.html (optional, only if you want to have a spa frontend, you can imports client scripts from here)
server.ts (optional, only if you want to have a backend)
auth.ts (optional, only if you want to use better-auth)
schema.ts (optional, only if you want to use drizzle-orm)
m3-stack.config.ts (optional, only if you want to change some config)
You can also use src
index.html
m3-stack.config.ts
src/
server.ts
auth.ts
schema.ts
You can also do deeper levels of nesting.
index.html
m3-stack.config.ts
src/
server/
main.ts
auth/
index.ts
schema/
index.ts
The stack will automatically search for the entrypoints.
Entrypoints:
./src/(server|auth|schema)/(index|main).(ts|js|tsx|jsx)
./(server|auth|schema)/(index|main).(ts|js|tsx|jsx)
./src/lib/(server|auth|schema)/(index|main).(ts|js|tsx|jsx)
Config target:
./m3-stack.config.(ts|js)
./.config/m3-stack.(ts|js)
"m3-stack" field in package.json
WARNING This command is not working currently. You must create files by hand. Sorry :(.
npx m3-stack create my-app
npx m3-stack dev
Build frontend and backend.
npx m3-stack build
Output package can be found in dist folder. You can just copy the output and run it with node. You don't need to install any dependencies to run bundled app.
It will automatically search for server entrypoint to bundle it.
Default paths:
It will automatically search for index html and public/
dir to bundle client code.
Example dir structure:
my-app/
public/
index.html (with a script pointing to client/main.tsx)
src/
server/
main.ts
client/
main.tsx
npx m3-stack dev
It will start a dev server for frontend and backend. It will watch for changes and rebuild automatically. For the frontend, it will serve index.html on all routes.
For the backend, it will server the backend at '/api'. You can add more routes in config to be served from backend directly. For example '/blog/(.*)' can be served from backend instead of client app.
Include:
better-auth
SetupIf you use your own implementation check better auth docs. On how to generate schema. I personally recommend using drizzle-orm
which comes
by default with this stack.
Using m3-stack defaults
// m3-stack.config.ts
import { createConfig } from "m3-stack/config";
import { createAuth } from "./src/auth";
import { createDb, schema } from "./src/db";
const db = createDb();
export default createConfig({
...
drizzleSchema: schema,
betterAuth: createAuth({ db }),
...
})
npx m3-stack better-auth generate
src/db/schema/auth.ts
file (or where you put your drizzle-orm
schema).
You can add columns to the schema but be careful to not break important things.FAQs
m3-stack is a library with a set of tools and utilities to build, bundle and deploy web apps with react and backend with nodejs.
We found that m3-stack demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers 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.
Security News
Django has updated its security policies to reject AI-generated vulnerability reports that include fabricated or unverifiable content.
Security News
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
Security News
A new Node.js homepage button linking to paid support for EOL versions has sparked a heated discussion among contributors and the wider community.