Project Structure
Understand the monorepo structure, file organization, and naming conventions used in BISO SItes.
Project Structure
This guide explains how the BISO Sites monorepo is organized, including directory structures, naming conventions, and the purpose of each major file and folder.
Monorepo Overview
BISO SItes uses Turborepo to manage a monorepo with multiple applications and shared packages. This allows code sharing, consistent tooling, and atomic commits across all projects.
biso-sites/
├── apps/ # Applications (Next.js apps)
├── packages/ # Shared packages
├── node_modules/ # Root dependencies
├── package.json # Root workspace configuration
├── turbo.json # Turborepo pipeline configuration
└── bun.lock # Dependency lockfileRoot Level Files
Configuration Files
| File | Purpose |
|---|---|
package.json | Root workspace config, defines scripts and workspaces |
turbo.json | Turborepo task pipeline and caching configuration |
bun.lock | Lockfile for exact dependency versions |
.gitignore | Files and directories to exclude from Git |
Documentation Files
| File | Purpose |
|---|---|
README.md | Project overview (originally Turborepo template) |
AGENTS.md | Repository guidelines for AI agents and developers |
ARCHITECTURE_REFACTOR.md | Documentation of architectural changes |
DOCS_PROGRESS.md | Track documentation completion |
Quality & Configuration
| File | Purpose |
|---|---|
knip.json | Configuration for unused code detection |
.editorconfig | Editor configuration for consistent formatting |
Applications (apps/)
Each Next.js application follows the same conventions—src/app for routes, colocated components, and per-app configuration files.
Use the tabs below to explore the directory structure for each app without scrolling through three separate sections.
The public-facing site consumed by students and visitors.
| App | Port | Purpose | Key References |
|---|---|---|---|
| Web | 3000 | Public website for students and visitors | Web App Docs |
| Admin | 3001 | CMS for editors and IT managers | Admin App Docs |
| Docs | 3002 | This documentation site | Docs Architecture |
Packages (packages/)
Shared code used across multiple applications.
API Package (packages/api/)
Appwrite client wrappers and utilities.
packages/api/
├── client.ts # Client-side API (browser)
├── server.ts # Server-side API (Node.js)
├── storage.ts # Storage utilities
├── index.ts # Main exports
├── types/ # TypeScript type definitions
│ └── appwrite.ts
├── package.json
└── tsconfig.jsonUsage:
// Server-side
import { createSessionClient } from '@repo/api/server';
// Client-side
import { Client, Account } from '@repo/api/client';
// Storage helpers
import { getStorageFileUrl } from '@repo/api';UI Package (packages/ui/)
Shared React components based on shadcn/ui.
packages/ui/
├── components/
│ ├── ui/ # shadcn/ui components
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── patterns/ # Composite patterns
│ └── theme-provider.tsx
├── lib/
│ ├── utils.ts # Utility functions (cn, etc.)
│ ├── fonts.ts # Font definitions
│ └── tokens.ts # Design tokens
├── styles/
│ └── globals.css # Global styles
├── hooks/
│ └── use-mobile.ts
└── package.jsonUsage:
import { Button } from '@repo/ui/components/ui/button';
import { ThemeProvider } from '@repo/ui/components/theme-provider';Editor Package (packages/editor/)
Puck editor configuration for visual page building.
packages/editor/
├── components/ # Custom Puck components
│ ├── button.tsx
│ ├── heading.tsx
│ ├── section.tsx
│ └── text.tsx
├── editor.tsx # Editor component
├── renderer.tsx # Render engine
├── page-builder-config.tsx # Puck configuration
├── types.ts # TypeScript types
└── package.jsonThe editor package is actively being developed. Future versions will support more components and advanced features.
Payment Package (packages/payment/)
Payment provider integrations (currently Vipps).
packages/payment/
├── vipps.ts # Core Vipps logic (framework-agnostic)
├── actions.ts # Server actions for Next.js
├── types/ # TypeScript types
├── package.json
└── README.mdKey Feature: Framework-agnostic with dependency injection pattern.
Usage:
// In Next.js Server Actions
import { initiateVippsCheckout } from '@repo/payment/actions';
// Direct usage (pass db manually)
import { createCheckoutSession } from '@repo/payment/vipps';Configuration Packages
ESLint Config (packages/eslint-config/)
packages/eslint-config/
├── base.js # Base ESLint rules
├── next.js # Next.js-specific rules
├── react-internal.js # React component rules
└── package.jsonTypeScript Config (packages/typescript-config/)
packages/typescript-config/
├── base.json # Base TypeScript config
├── nextjs.json # Next.js-specific config
├── react-library.json # React library config
└── package.jsonApp-Level Structure
Typical Next.js App Structure
Each Next.js app follows this pattern:
app/
├── (route-groups)/ # Grouped routes (shared layouts)
│ ├── layout.tsx
│ └── page.tsx
├── actions/ # Server Actions
│ └── feature.ts
├── api/ # API Routes
│ └── route/
│ └── route.ts
├── layout.tsx # Root layout
├── page.tsx # Home page
├── globals.css # Global styles
└── fonts.ts # Font definitionsComponent Organization
Components are organized by type:
components/
├── ui/ # Generic UI components
├── features/ # Feature-specific components
├── layouts/ # Layout components
├── forms/ # Form components
└── shared/ # Shared across featuresLibrary Code
lib/
├── utils.ts # Generic utilities
├── constants.ts # App constants
├── types.ts # Type definitions
├── api/ # API wrappers
└── hooks/ # Custom React hooksNaming Conventions
Files
| Type | Convention | Examples |
|---|---|---|
| Components | PascalCase | Button.tsx, UserProfile.tsx |
| Utilities | kebab-case | format-date.ts, api-client.ts |
| Routes | kebab-case | user-profile/, about-us/ |
| Constants | UPPERCASE | CONSTANTS.ts, API_ENDPOINTS.ts |
Directories
| Type | Convention | Examples |
|---|---|---|
| Route Groups | (parentheses) | (auth)/, (admin)/ |
| Features | kebab-case | user-profile/, payment-flow/ |
| Components | PascalCase folders OK | Button/, components/ |
Code
// Components: PascalCase
export function UserProfile() {}
export const Button = () => {}
// Functions: camelCase
export function formatDate() {}
export const getUserData = () => {}
// Constants: UPPER_SNAKE_CASE
export const API_ENDPOINT = '/api';
export const MAX_ITEMS = 100;
// Types/Interfaces: PascalCase
export type User = {};
export interface ButtonProps {}Special Directories
Route Groups (name)/
Route groups organize routes without affecting the URL:
app/
├── (auth)/ # Auth routes, won't show "(auth)" in URL
│ ├── login/
│ └── register/
├── (admin)/ # Admin routes
│ └── dashboard/
└── (public)/ # Public routes
└── about/URL: /login, /dashboard, /about (group names not in URL)
Private Folders _name/
Folders starting with _ are private and excluded from routing:
app/
├── _components/ # Private components
├── _lib/ # Private utilities
└── page.tsx # Public routeAPI Routes
app/api/
├── users/
│ └── route.ts # GET/POST /api/users
├── posts/
│ └── [id]/
│ └── route.ts # GET/PUT /api/posts/[id]Import Paths
Absolute Imports
TypeScript is configured for absolute imports:
// ✅ Good: Absolute from src
import { Button } from 'components/ui/button';
import { formatDate } from '@/lib/utils';
// ❌ Avoid: Relative imports that are deep
import { Button } from '../../../components/ui/button';Package Imports
// Import from packages
import { Button } from '@repo/ui/components/ui/button';
import { createSessionClient } from '@repo/api/server';
import { initiateVippsCheckout } from '@repo/payment/actions';Configuration Files per App
Each app has these config files:
app/
├── next.config.ts # Next.js configuration
├── tsconfig.json # TypeScript config (extends base)
├── tailwind.config.cjs # Tailwind CSS config
├── postcss.config.js # PostCSS config
├── eslint.config.js # ESLint config
└── package.json # App dependencies & scriptsEnvironment Files
app/
├── .env.local # Local environment (gitignored)
├── .env.example # Example environment variables
├── .env.development # Development defaults (optional)
└── .env.production # Production defaults (optional)Only .env.local is gitignored. Never commit secrets! Always use .env.example for documentation.
Static Assets
public/
├── images/
│ ├── hero/
│ └── logos/
├── fonts/
├── icons/
└── favicon.icoAccess in code:
<Image src="/images/logo.png" alt="Logo" />i18n Structure
Translation files for internationalization:
messages/
├── en/
│ ├── common.json
│ ├── home.json
│ └── about.json
├── no/
│ ├── common.json
│ ├── home.json
│ └── about.json
├── en.ts # English exports
└── no.ts # Norwegian exportsBuild Outputs
Build artifacts (gitignored):
app/
├── .next/ # Next.js build output
├── dist/ # Package build output
├── node_modules/ # Dependencies
└── .turbo/ # Turborepo cacheKey Takeaways
- Monorepo structure enables code sharing and consistency
- Apps are standalone Next.js applications
- Packages contain shared code used by multiple apps
- Turborepo manages the build pipeline and caching
- Conventions ensure consistency across the codebase
Now that you understand the structure, learn about the Architecture or dive into Development Workflow.
