Ludicord
Guide 03 · Start here

Project structure

Learn what every generated file owns and how conventions become routes.

Ludicord 3.1.0Public source 20c4889
Route ownershipFiles become explicit runtime boundaries
Framework managed
activity/app

app/

pages.tsxshell

embeds/home/embed.tsxscreen

api/score/route.tsHTTP

ws/room/route.tsrealtime

generatedTyped route manifest

The compiler links each file to the runtime that owns it.

screenshandlersrooms

Ludicord uses file conventions: location and filename determine what a module becomes. The generator starts small, while the framework supplies built-in fallbacks for optional convention files.

#Generated application tree

texttext
1app/
2├── pages.tsx
3├── globals.css
4├── minimize.tsx
5├── auth/
6│ ├── loading.tsx
7│ ├── error.tsx
8│ └── denied.tsx
9├── embeds/
10│ ├── home/embed.tsx
11│ └── me/embed.tsx
12├── api/
13│ └── hello/route.ts
14└── ws/
15 └── audience/route.ts

The starter also includes components/, lib/, public/, ludicord.config.mjs, environment templates, generated route declarations, and TypeScript configuration.

#What each location owns

LocationResponsibilityRuns in
app/pages.tsxPersistent Activity root and providersBrowser
app/globals.cssGlobal styles, safe-area variables, Tailwind importBrowser
app/minimize.tsxCompact UI Discord shows while minimizedBrowser
app/auth/*Automatic authorization loading, error, and denied statesBrowser
app/embeds/**/embed.tsxNavigable Activity screensBrowser
app/api/**/route.tsTrusted HTTP method handlersServer
app/ws/**/route.tsAuthenticated WebSocket endpointsServer
public/Static assets served from the root URLBrowser

Do not import a server route into a client component. Communicate across the boundary with fetch() or useWS().

#How paths become routes

The folders under embeds, api, and ws become URL segments. Route groups in parentheses organize code without changing the public path.

texttext
1app/embeds/home/embed.tsx → home
2app/embeds/profile/[id]/embed.tsx → profile/:id
3app/embeds/(games)/chess/embed.tsx → chess
4app/api/player/[id]/route.ts → /api/player/:id
5app/ws/room/[roomId]/route.ts → /ws/room/:roomId

Starting development or a build updates ludicord.generated.d.ts. This makes route strings and dynamic params available to TypeScript without a manual route registry.

#The fixed filenames

An embed component is always embed.tsx and should default-export a React component named embed. An HTTP or WebSocket module is always route.ts. The stable names let the compiler distinguish framework boundaries from ordinary colocated modules.

app/embeds/game/embed.tsxtsx
1export default function embed() {
2 return <main>Game screen</main>;
3}

Components, helpers, schemas, tests, and assets may live beside a route. Only recognized convention filenames become public routes.

#Root and nested boundaries

pages.tsx owns providers that should survive screen navigation. Embed folders can add nested layout.tsx files and nearest loading or error boundaries when advanced sections need them. Keep ordinary screen-specific UI beside the embed that uses it.

#Files outside app

File or folderPurpose
ludicord.config.mjsRuntime and build configuration
.env.localLocal secrets; never commit it
ludicord-env.d.tsCSS and environment declarations
ludicord.generated.d.tsGenerated route/config types
components/Shared React components
lib/Shared browser-safe helpers; use explicit server modules for secrets

#Next step

Configure Discord setup before depending on real user, guild, channel, or Activity-instance data.