Opinionated React SSR framework built on Vite. Compiles components, renders pages server-side, and integrates with backend CMS projects.
npx alveo create my-app
cd my-app
bun install
bun run dev| Command | Description |
|---|---|
alveo dev |
Start dev server with HMR, style watcher, and SSR |
alveo build |
Production build (static + SSR bundles) |
alveo generate |
Full pipeline: states, styles, build, prerender |
alveo inte |
Integration build for backend consumption |
alveo styles |
Compile SCSS stylesheets |
alveo styles --watch |
Watch and recompile SCSS on changes |
alveo states |
Aggregate component state JSON files |
alveo create <name> |
Scaffold a new project from the starter template |
All commands accept --root <path> to specify the project root (defaults to cwd).
A consumer project looks like this:
my-app/
src/
assets/styles/ SCSS stylesheets (abstracts, functions, mixins, base)
atoms/ Atomic design: smallest UI elements
molecules/ Composed atoms
organisms/ Composed molecules (each gets its own CSS)
templates/ Page layout templates
pages/ Page components (auto-discovered for routing)
_helpers/ Utility components (RequireJs, RequireCss, ReactSection)
_data/ Static data
_api/ API client modules
mocks/ MSW mock handlers
client-components.tsx Registry of client-rendered React components
public/
assets/images/ SVG sprites, icons
assets/fonts/ Web fonts
assets/vendors/ Third-party libraries
index.html HTML template
vite.config.ts Vite config (calls defineAlveoConfig)
tsconfig.json TypeScript config
.env Environment variables
import { defineAlveoConfig } from 'alveo';
export default defineAlveoConfig({
root: import.meta.dirname,
});VITE_BASE_URL=/
VITE_PORT=15889
VITE_PATH_EXTENSION='.html'
VITE_TITLE_SUFFIX='My App'
# Integration paths (for alveo inte)
VITE_INTE_ASSET_DIR=../MyProject.Web/wwwroot/assets
VITE_INTE_PATTERN_DIR=../MyProject.Patterns{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"skipLibCheck": true,
"paths": {
"@atoms/*": [
"./src/atoms/*"
],
"@molecules/*": [
"./src/molecules/*"
],
"@organisms/*": [
"./src/organisms/*"
],
"@templates/*": [
"./src/templates/*"
],
"@pages/*": [
"./src/pages/*"
],
"@helpers/*": [
"./src/_helpers/*"
],
"@data/*": [
"./src/_data/*"
],
"@mocks/*": [
"./src/mocks/*"
]
}
}
}| Alias | Resolves to |
|---|---|
@atoms/* |
src/atoms/* |
@molecules/* |
src/molecules/* |
@organisms/* |
src/organisms/* |
@templates/* |
src/templates/* |
@pages/* |
src/pages/* |
@helpers/* |
src/_helpers/* |
@data/* |
src/_data/* |
@mocks/* |
src/mocks/* |
@alveo/* |
alveo package internals |
Register React components for client-side hydration in src/client-components.tsx:
import { lazy } from 'react';
export const clientComponents = {
header: lazy(() => import('./organisms/header')),
people: lazy(() => import('./organisms/people')),
};These render in the browser from <script data-rct="header"> tags in your HTML.
src/assets/styles/style-base.scss— main stylesheet entry pointsrc/organisms/{name}/index.scss— per-organism styles, compiled tob-{name}.csssrc/templates/{name}/index.scss— per-template styles, compiled top-{name}.css- Abstracts, functions, and mixins barrels are auto-injected as
@usepreludes
| Command | Output |
|---|---|
alveo build |
dist/static/ (client), dist/server/entry-server.js (SSR) |
alveo generate |
Pre-rendered HTML pages in dist/static/pages/ |
alveo inte |
Copies assets to VITE_INTE_ASSET_DIR, patterns to VITE_INTE_PATTERN_DIR |
alveo styles |
CSS files in public/assets/css/ |
bun installbun run buildbun run test
bun run test:coveragebun run typecheck- Node.js >= 20 or Bun
- React 19
- TypeScript 5+
MIT