Version: 1.11.0 | Updated: 2025-02-08
core/is read-only framework code - NEVER modifyapp/contains all user application codeconfig/holds declarative configuration filesplugins/is for external plugin development- Path aliases simplify imports across the project
Rule: NEVER modify files in core/
core/
├── framework/ # Core framework server and lifecycle
├── plugins/ # Plugin system (manager, registry, types)
├── server/ # Server utilities (live components, middleware)
├── client/ # Client-side framework utilities
├── build/ # Build system and bundling
├── cli/ # CLI commands and generators
├── utils/ # Framework utilities
├── types/ # Framework type definitions
└── templates/ # Code generation templates
Why read-only?
- Framework updates would overwrite your changes
- Breaking changes could occur on version upgrades
- Customization should happen through plugins or app code
What to do instead:
- Create plugins in
plugins/for framework extensions - Override behavior using plugin hooks
- Implement custom logic in
app/
Rule: All your application code goes here
app/
├── server/ # Backend code
│ ├── routes/ # API route definitions (Eden Treaty)
│ ├── controllers/# Business logic and services
│ ├── live/ # Live component implementations
│ ├── websockets/ # WebSocket handlers
│ ├── utils/ # Server-side utilities
│ ├── app.ts # Elysia app configuration
│ └── index.ts # Server entrypoint
├── client/ # Frontend code
│ ├── src/ # React application source
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── hooks/ # Custom React hooks
│ │ ├── stores/ # State management (Zustand)
│ │ ├── utils/ # Client-side utilities
│ │ ├── App.tsx # Root component
│ │ └── main.tsx # React entrypoint
│ ├── public/ # Static assets
│ └── index.html # HTML template
└── shared/ # Shared code between client and server
└── types/ # Shared TypeScript types
Organization principles:
- server/routes/: Define API endpoints with schemas
- server/controllers/: Implement business logic (keep routes thin)
- client/src/: All React code and frontend logic
- shared/types/: Types used by both frontend and backend
config/
├── system/ # Framework system configs (rarely modified)
│ ├── app.config.ts
│ ├── server.config.ts
│ ├── client.config.ts
│ ├── build.config.ts
│ ├── plugins.config.ts
│ └── ...
├── app.config.ts # Application-specific config
├── server.config.ts # Server configuration
├── client.config.ts # Client configuration
├── database.config.ts # Database configuration
├── plugins.config.ts # Plugin configuration
└── index.ts # Config aggregator
Two-tier system:
config/system/: Framework defaults (usedefineConfig)config/*.config.ts: User overrides and custom configs
Best practices:
- Override system configs by creating same-named file in
config/ - Use
defineConfigfor type safety and validation - Keep sensitive values in environment variables
plugins/
└── your-plugin/
├── index.ts # Plugin entrypoint
├── server/ # Server-side plugin code
├── client/ # Client-side plugin code
└── package.json # Plugin metadata
When to create a plugin:
- Reusable functionality across projects
- Framework extensions (new hooks, middleware)
- Third-party integrations
- Shareable with community
When NOT to use plugins:
- Application-specific business logic → use
app/ - Simple utilities → use
app/server/utils/orapp/client/utils/
- kebab-case for directories:
user-management/,auth-service/ - kebab-case for files:
user-controller.ts,auth-utils.ts - PascalCase for React components:
UserProfile.tsx,LoginForm.tsx - camelCase for utility files:
formatDate.ts,apiClient.ts
Routes:
app/server/routes/
├── users.ts # /users endpoints
├── auth.ts # /auth endpoints
└── admin/
└── dashboard.ts # /admin/dashboard endpoints
Controllers:
app/server/controllers/
├── UserController.ts
├── AuthController.ts
└── services/
├── UserService.ts
└── AuthService.ts
React Components:
app/client/src/components/
├── UserProfile.tsx
├── LoginForm.tsx
└── common/
├── Button.tsx
└── Input.tsx
Types:
app/shared/types/
├── user.types.ts
├── auth.types.ts
└── api.types.ts
Configured in tsconfig.json:
{
"paths": {
"@core/*": ["./core/*"], // Framework code
"@app/*": ["./app/*"], // Application root
"@server/*": ["./app/server/*"], // Server code
"@client/*": ["./app/client/*"], // Client code
"@shared/*": ["./app/shared/*"], // Shared code
"@config": ["./config/index.ts"], // Config aggregator
"@config/*": ["./config/*"] // Individual configs
}
}Server-side imports:
// ✅ Good - Use aliases
import { UserController } from '@server/controllers/UserController'
import { UserType } from '@shared/types/user.types'
import { serverConfig } from '@config'
// ❌ Bad - Relative paths
import { UserController } from '../../server/controllers/UserController'
import { UserType } from '../../../shared/types/user.types'Client-side imports:
// ✅ Good - Use aliases
import { UserProfile } from '@client/components/UserProfile'
import { useAuth } from '@client/hooks/useAuth'
import { UserType } from '@shared/types/user.types'
// ❌ Bad - Relative paths
import { UserProfile } from '../components/UserProfile'
import { useAuth } from '../../hooks/useAuth'Plugin imports:
// ✅ Good - Import from core for plugin development
import type { FluxStackPlugin } from '@core/types/plugin.types'
import { logger } from '@core/utils/logger'
// ✅ Good - Import app code if needed
import { UserType } from '@shared/types/user.types'- Always use aliases for cross-directory imports
- Relative paths OK for same-directory imports:
./utils,./types - Never import from
core/in app code (except types) - Use
@shared/*for code used by both client and server
- Define types in
app/shared/types/feature.types.ts - Create route in
app/server/routes/feature.ts - Implement controller in
app/server/controllers/FeatureController.ts - Build UI in
app/client/src/pages/FeaturePage.tsx - Use Eden Treaty in client to call API with type safety
- Create config file in
config/feature.config.ts - Use
defineConfigfor schema and validation - Export from
config/index.ts - Import with
@configalias
- Create directory in
plugins/my-plugin/ - Implement interface from
@core/types/plugin.types - Add to whitelist in
config/plugins.config.ts - Framework auto-discovers on startup