nist-stack
v1.0.10
Published
NIST Framework - NestJS + Vite SSR for React
Maintainers
Readme
Why NIST?
NIST combines NestJS's powerful backend architecture with Vite's lightning-fast development experience to deliver server-side rendered React applications with unprecedented performance and developer experience.
// Define your page in a NestJS controller
@Get()
@Page("home")
getHome(): PageResponse {
return { data: { users: ["Alice", "Bob"] } };
}// Render with React - props are fully typed!
export default function Home({ users }) {
return (
<ul>
{users.map((u) => (
<li key={u}>{u}</li>
))}
</ul>
);
}Result: Sub-20ms SSR, full type safety, and instant HMR. No configuration needed.
At a Glance
| Feature | NIST | Next.js | Remix | | ------------------------ | ---------------- | -------------------- | ----------------- | | Backend Framework | Full NestJS | Limited API routes | Express-like | | SSR Performance | ~19ms (cached) | ~150-300ms | ~200-400ms | | Dependency Injection | ✅ Built-in | ❌ Manual | ❌ Manual | | Type Safety | ✅ End-to-end | ⚠️ Partial | ⚠️ Partial | | Guards & Auth | ✅ NestJS guards | ⚠️ Custom middleware | ⚠️ Custom loaders | | Build Tool | Vite 7 | Turbopack | esbuild | | Hot Reload | ✅ Instant HMR | ✅ Fast Refresh | ✅ Live reload |
Quick Start
Installation
npm install nist-stackThat's it! One package gives you everything.
1. Server Setup (main.ts)
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { bootstrapNist } from "nist-stack";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await bootstrapNist(app); // One line setup!
await app.listen(3000);
}
bootstrap();2. Create a Controller with Pages
import { Controller, Get } from "@nestjs/common";
import { Page, PageRoot } from "nist-stack";
@Controller()
@PageRoot(__dirname)
export class AppController {
@Get("/")
@Page("app")
home() {
return { users: ["Alice", "Bob"] };
}
}3. Create Root Layout (src/app.layout.tsx)
import type { LayoutProps } from "nist-stack/client";
export default function AppLayout({
children,
metaTags, // Required for SEO
hydrationScripts, // Required for React hydration
metadata,
}: LayoutProps) {
const isClient = typeof window !== "undefined";
if (isClient) return <>{children}</>;
return (
<html lang="en">
<head>
<meta charSet="UTF-8" />
<title>{metadata?.title || "My App"}</title>
{metaTags}
</head>
<body>
<div id="root">{children}</div>
{hydrationScripts}
</body>
</html>
);
}4. Create a React Page (src/app.page.tsx)
import { Link } from "nist-stack/client";
export default function App({ users }) {
return (
<div>
<h1>Users</h1>
<ul>
{users.map((u) => (
<li key={u}>{u}</li>
))}
</ul>
<Link href="/about">About</Link>
</div>
);
}5. Create the Vite client entry (src/entry-client.tsx)
import "./globals.css";
import { createClientEntry } from "nist-stack/client";
const globals = window as any;
// Discover all pages and layouts relative to @PageRoot(__dirname)
// @ts-ignore - Vite-specific import.meta.glob helper
const pages = import.meta.glob(["/src/**/*.page.tsx", "/app/**/*.page.tsx"], {
eager: false,
});
// @ts-ignore - Vite-specific import.meta.glob helper
const layouts = import.meta.glob(
["/src/**/*.layout.tsx", "/app/**/*.layout.tsx"],
{ eager: false }
);
const { render } = createClientEntry({
globals,
pages,
layouts,
targetId: "root",
});
render();
// Enable hot module replacement during development
// @ts-ignore - Vite HMR typings
if (import.meta.hot) {
// @ts-ignore - Vite HMR typings
import.meta.hot.accept(Object.keys(pages), async () => {
await render();
});
}✅ The client entry wires Vite + React hydration. Keep it at
src/entry-client.tsxsobootstrapNistcan inject the scripts automatically.
6. Configure Vite (vite.config.ts)
import { resolve } from "path";
import { createConfig } from "nist-stack";
export default createConfig({
resolve: {
alias: {
"@": resolve(__dirname, "./src"),
},
},
});
createConfig()sets up SSR + HMR defaults. Add aliases or plugins here as you would in a normal Vite project.
Available Imports
Server-Side
// From 'nist-stack'
import {
Page, // Decorator: Mark controller method as page
PageRoot, // Decorator: Set page root directory
Layout, // Decorator: Set custom layout
NistInterceptor, // SSR interceptor
createViteDevServer, // Create Vite server
NistError, // Framework error class
} from "nist-stack";
// From 'nist-stack/decorators' (alternative)
import { Page, PageRoot, Layout } from "nist-stack/decorators";Client-Side
// From 'nist-stack/client'
import {
Link, // Client-side navigation component
Image, // Optimized image component
ErrorBoundary, // Error boundary component
Router, // Router component
useRouter, // Router hook
useParams, // Get route params
useQuery, // Get query params
usePathname, // Get current pathname
useParam, // Get single param
useQueryParam, // Get single query param
useRouteData, // Get all route data
useNistData, // Get full hydration data
} from "nist-stack/client";
// TypeScript types
import type {
Metadata, // Page/layout metadata
LayoutProps, // Layout component props
PageProps, // Page component props
PageConfig, // Page configuration (ISR, etc.)
RouteData, // Route data interface
} from "nist-stack/client";Features
- ✅ Server-Side Rendering (SSR)
- ✅ Hot Module Replacement (HMR)
- ✅ Type-safe routing with decorators
- ✅ Automatic page validation
- ✅ Built-in security (CSRF, XSS protection)
- ✅ Production-ready builds
- ✅ Client-side navigation
- ✅ SEO metadata support
- ✅ ISR support (Incremental Static Regeneration)
Examples
Simple Page
// my-page.page.tsx
export default function MyPage() {
return <div>Hello World</div>;
}Using Route Params
import { useParams } from "nist-stack/client";
export default function UserPage() {
const { id } = useParams<{ id: string }>();
return <div>User ID: {id}</div>;
}Custom Layout
// app.layout.tsx
export default function Layout({ children }) {
return (
<div>
<nav>Navigation</nav>
{children}
</div>
);
}Controller with Layout
import { Controller, Get } from "@nestjs/common";
import { Page, PageRoot, Layout } from "nist-stack";
@Controller()
@PageRoot(__dirname)
export class AppController {
@Get("/profile")
@Page("profile")
@Layout("app") // Use app.layout.tsx
profile() {
return { user: { name: "Alice" } };
}
}Development
The framework is optimized for hot reloading:
- Frontend changes → Vite HMR (instant updates, no page reload)
- Backend changes → NestJS restarts (Vite HMR preserved)
Run with your preferred NestJS dev tool:
# Using ts-node-dev
ts-node-dev --respawn --transpile-only src/main.ts
# Using nodemon
nodemon --watch src -e ts --exec ts-node src/main.ts
# Using NestJS CLI
nest start --watchThe Vite dev server persists across NestJS restarts, so frontend HMR is never interrupted.
Production Build
# Build everything
npm run build
# Start production server
npm run start:prodThe framework automatically switches between dev (HMR) and production (static bundles) based on NODE_ENV.
TypeScript Configuration
Full TypeScript support out of the box. All exports are typed.
Development vs Production Configuration
NIST requires two separate TypeScript configs to prevent conflicts between NestJS compilation and Vite HMR:
1. tsconfig.build.json (for development - excludes .tsx):
{
"extends": "./tsconfig.json",
"exclude": [
"node_modules",
"test",
"dist",
"**/*spec.ts",
"public",
"**/*.tsx"
]
}2. tsconfig.prod.json (for production builds - includes .tsx):
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"declaration": true
},
"include": ["src/**/*", "src/**/*.tsx"],
"exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"]
}Key points:
- ✅
tsconfig.build.jsonexcludes**/*.tsx- preventsnest start --watchfrom compiling React files - ✅
tsconfig.prod.jsonincludes"src/**/*.tsx"- compiles pages/layouts for production - ✅ Development: Vite handles all
.tsxcompilation with HMR - ✅ Production: TypeScript compiles
.tsxfiles to JavaScript - ⚠️ Without the exclude in build config, NestJS will try to compile
.tsxfiles and break HMR
License
MIT
Who Should Use NIST?
Perfect for:
- 🏢 Enterprise applications requiring robust backend architecture
- 🔐 Auth-heavy applications with complex permission systems
- 📊 Data-intensive apps with significant server-side logic
- 🚀 Performance-critical applications needing fast SSR
- 🧩 Microservices architectures wanting consistent frontend
Documentation
- 📚 Full Documentation
- 🚀 Getting Started Guide
- 📖 API Reference
- 🎯 Examples
- 🔧 Configuration
- 🚢 Deployment Guide
Community & Support
- 💬 GitHub Discussions - Ask questions and share ideas
- 🐛 Issue Tracker - Report bugs and request features
- 📧 Email Support - For private inquiries
- 💼 Enterprise Support - Professional support options
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Security
Found a security vulnerability? Please review our Security Policy and report it responsibly.
Changelog
See CHANGELOG.md for release notes and version history.
License
MIT
Acknowledgments
Built with:
- NestJS - Progressive Node.js framework
- Vite - Next generation frontend tooling
- React - Library for building user interfaces
