Documentation

Project Structure

Understand the anatomy of a Frame-Master project and how different directories and files work together to create your application.

Overview

A typical Frame-Master project follows a simple, organized structure that separates configuration, source code, and internals:

project-structure
my-frame-master-app/
├── frame-master.config.ts # Main configuration
├── bunfig.toml # Bun configuration
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies
├── .frame-master/ # Framework internals (auto-generated)
│ ├── build/ # Build utilities
│ ├── server.ts # Server setup
│ ├── preload.ts # Runtime preloader
│ └── frame-master-custom-type.d.ts
└── src/ # Your application code (plugin-dependent)
💡

Plugin-Driven Structure

Frame-Master is a minimal core framework. The src/ directory structure depends entirely on which plugins you install. Plugins like frame-master-plugin-react-ssr add file-based routing with pages/ directories, while other plugins may have different structures.

Configuration Files

frame-master.config.ts

The heart of your Frame-Master application

This is the main configuration file where you define your server settings, plugins, and application behavior.

frame-master.config.ts
import type { FrameMasterConfig } from "frame-master/server/type";
const config: FrameMasterConfig = {
HTTPServer: {
port: 3000,
host: "localhost",
},
plugins: [
// Add plugins here to extend functionality
// Example: reactPlugin(), tailwindPlugin(), etc.
],
};
export default config;

Key Options:

  • HTTPServer - Server port, host, and other HTTP settings
  • plugins - Array of plugin instances that extend functionality

bunfig.toml

Bun-specific configuration

Configures Bun runtime behavior, including module resolution, preloading, and build settings.

bunfig.toml
[install]
# Configure package installation
registry = "https://registry.npmjs.org/"
[run]
# Preload scripts before running
preload = ["./.frame-master/preload.ts"]

tsconfig.json

TypeScript compiler configuration

Defines TypeScript compiler options and path aliases for your project.

tsconfig.json
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src", ".frame-master/frame-master-custom-type.d.ts"]
}

package.json

Project metadata and dependencies

Standard Node.js package file containing your project's dependencies, scripts, and metadata.

package.json
{
"name": "frame-master-site",
"type": "module",
"private": true,
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
},
"dependencies": {
"frame-master": "^1.0.1",
},
"scripts": {
"dev": "NODE_ENV=development bun --hot frame-master dev",
"start": "NODE_ENV=production bun frame-master start"
}
}

.frame-master Directory

Auto-generated framework internals that power your application. You typically don't need to modify these files.

build/

Contains build utilities and transpilation logic for your application code.

server.ts

The main server entry point that initializes the HTTP server, loads plugins, and handles requests.

preload.ts

Runtime preloader that sets up the environment before your application code runs. Loaded via bunfig.toml.

frame-master-custom-type.d.ts

TypeScript type definitions for Frame-Master globals and plugin-specific types.

src Directory

Your application source code lives here. The exact structure is defined by the plugins you install.

⚠️

Plugin-Dependent Structure

Frame-Master core does not prescribe any specific src/ directory structure. The layout below is an example from the frame-master-plugin-react-ssr plugin, which implements file-based routing. Other plugins may use completely different structures, or you can create your own custom organization.

Example: React SSR Plugin Structure

When using the React SSR plugin, you get file-based routing with pages and layouts

file-based-routing
src/pages/
├── index.tsx # / route
├── layout.tsx # Root layout wrapper
├── about/
│ └── index.tsx # /about route
├── blog/
│ ├── index.tsx # /blog route
│ ├── layout.tsx # Blog layout wrapper
│ └── [slug]/
│ └── index.tsx # /blog/:slug dynamic route
└── api/
└── users.ts # /api/users API endpoint

This structure is specific to the React SSR plugin. See the React SSR Plugin documentation for details.

Common src/ Directories

Regardless of plugins, these directories are commonly used

🔧

src/utils/

Utility functions and helper modules shared across your application

🗄️

src/lib/

Third-party library integrations, configurations, and API clients

🎨

src/styles/

Global styles, CSS modules, or style utilities (if your plugin supports it)

🔌

src/plugins/

Custom Frame-Master plugins specific to your project

Plugin-Added Directories

Plugins may add their own directories to your project structure

📁

static/

Some plugins (like React SSR) add a static/ directory for serving public assets like images, fonts, and CSS files directly.

📦

dist/ or build/

Build plugins may create output directories for compiled or bundled code.

⚙️

Plugin-Specific Directories

Each plugin can define its own directory structure. Check the plugin's documentation for details.

💡

Learn More

See the Plugin System documentation to understand how plugins extend Frame-Master's functionality and structure.

Environment Variables

Store sensitive configuration and environment-specific settings in .env files:

.env
# Server Configuration
PORT=3000
HOST=localhost
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# API Keys
API_KEY=your-secret-key
# Environment
NODE_ENV=development
⚠️

Security

  • Never commit .env files to version control
  • Add .env to your .gitignore
  • Use separate .env files for different environments
  • Document required variables in a .env.example file

Accessing Environment Variables

usage-example
// In Frame-Master config
const config: FrameMasterConfig = {
HTTPServer: {
port: parseInt(process.env.PORT || "3000"),
host: process.env.HOST || "localhost",
},
// ...
};
// In your application code
const apiKey = process.env.API_KEY;
const dbUrl = process.env.DATABASE_URL;

Version Control

Recommended .gitignore configuration:

.gitignore
# Dependencies
node_modules/
bun.lockb
# Environment files
.env
.env.local
.env.*.local
# Build output
dist/
build/
# OS files
.DS_Store
Thumbs.db
# IDE files
.vscode/
.idea/
*.swp
*.swo
# Logs
*.log
npm-debug.log*

Monorepo Setup

Frame-Master works great in monorepo setups. Here's an example using workspaces:

monorepo-structure
my-monorepo/
├── package.json # Root package.json with workspaces
├── apps/
│ ├── web/ # Frame-Master web app
│ │ ├── frame-master.config.ts
│ │ ├── package.json
│ │ └── src/
│ └── api/ # Another Frame-Master API
│ ├── frame-master.config.ts
│ ├── package.json
│ └── src/
├── packages/
│ ├── ui/ # Shared UI components
│ │ ├── package.json
│ │ └── src/
│ └── utils/ # Shared utilities
│ ├── package.json
│ └── src/
└── plugins/
└── custom-plugin/ # Custom Frame-Master plugin
├── package.json
└── index.ts

Root package.json for Workspaces

package.json
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"apps/*",
"packages/*",
"plugins/*"
],
"scripts": {
"dev": "bun --filter './apps/*' dev",
"build": "bun --filter './apps/*' build"
}
}

Best Practices

📁

Follow Plugin Conventions

Each plugin may have its own structure conventions. Follow the documentation for plugins you use to maintain consistency.

🔒

Protect Sensitive Data

Never commit secrets, API keys, or credentials. Use environment variables and keep .env files in .gitignore.

📝

Document Your Structure

Create a README.md explaining your project's structure, especially if you're using custom plugins or non-standard layouts.

🔄

Version Control .frame-master/

While auto-generated, committing .frame-master/ can help with debugging and ensure consistency across environments.

🎯

Use Path Aliases

Configure @/* path aliases in tsconfig.json for cleaner imports (e.g., import { utils } from '@/lib/utils').

Next Steps

Now that you understand the project structure, explore these topics: