Project organization
Status: Principle and design direction. Compiler discovery syntax remains draft.
Goldar applications are organized by imports and an application graph, not by mandatory source folders. The CLI nevertheless provides a small conventional project shape so a typical application needs no entry or asset configuration:
src/
index.ts
public/
tests/
src/index.ts default-exports the Application. Files beneath public/ retain their relative path
at the URL root in development and production. Unit and integration tests belong in tests/ and
remain ordinary project code rather than part of the application graph. Authors may begin with one
source file and introduce structure only when it helps.
One-file application
A small application may define its stores, data, routes, router, and application in src/index.ts:
src/
dashboard.hbs
index.ts
public/
tests/
app.test.ts
import DashboardView from "./dashboard.hbs";
import { Application, Data, Route, Router, Store } from "goldar";
class DashboardData extends Data {
load() {
return { message: "Hello" };
}
}
class DashboardStore extends Store {
count = 0;
increment() {
this.count += 1;
}
}
class DashboardRoute extends Route {
readonly data = {
dashboard: new DashboardData(),
};
readonly store = new DashboardStore();
render() {
return DashboardView({
dashboard: this.data.dashboard,
count: this.store.count,
onIncrement: () => this.store.increment(),
});
}
}
const router = new Router().addRoute("/", DashboardRoute);
export default new Application(router);
Run this conventional project with goldar dev or goldar build. Pass an explicit entry, for
example goldar dev ./src/preview.ts, when intentionally running another application definition.
The explicit entry bypasses conventional entry and config discovery.
A config file exists for custom build and process behavior, not because the runtime requires one.
For entryless build and dev, --config or a discovered goldar.config.* takes precedence over
src/index.*. An explicit entry cannot be combined with --config.
Feature folders
The same application may be grouped by feature:
src/
dashboard/
data.ts
dashboard.hbs
route.ts
store.ts
index.ts
index.ts explicitly imports the feature’s route:
import { Application, Router } from "goldar";
import { DashboardRoute } from "./dashboard/route.js";
const router = new Router().addRoute("/", DashboardRoute);
export default new Application(router);
Feature folders keep code that changes together near each other without introducing a new runtime abstraction.
Type folders
An application may instead group modules by role:
src/
data/
dashboard.ts
routes/
dashboard.ts
stores/
dashboard.ts
views/
dashboard.hbs
index.ts
Goldar treats this graph identically to the one-file and feature-folder versions.
Mixed organization
Large applications frequently benefit from a mixture:
src/
account/
data/
routes/
views/
admin/
data.ts
route.ts
view.hbs
components/
fancy-tabs.ts
shared/
stores/
index.ts
Folders communicate ownership to humans. They do not create implicit dependency scopes.
Optional route discovery
The compiler may discover route modules when explicitly configured:
import { defineConfig } from "goldar/cli";
export default defineConfig({
routes: {
include: ["./src/routes/**/*.ts"],
},
views: {
include: ["./src/**/*.hbs"],
},
});
Discovery produces a manifest equivalent to explicit registration. It must not create a second router with different behavior.
Compiler discovery must:
- Be opt-in.
- Produce inspectable output.
- Fail on duplicate or ambiguous paths.
- Report modules that do not export a valid route.
- Preserve the same server and client lifecycle as explicit registration.
Whether paths are declared by the route module or derived from filenames is a separate option. Moving a file must not silently change its URL unless filename-derived routing was explicitly selected.
Compiler configuration
The proposed discovery configuration belongs to the compiler and deployment pipeline. It may describe:
- An application entry override when
src/index.*is not appropriate. - Template include patterns.
- Optional route discovery.
- Custom-element registries.
- Server and client output targets.
- Rendering and streaming defaults.
- Development tooling.
Application behavior remains in application code. Authentication rules, domain services, resource policies, and route composition should not migrate into build configuration merely because a config file exists.
Package organization
Reusable features may ship as ordinary packages containing any combination of:
- Route classes.
- Data resources.
- Stores.
- Form actions.
- Compiled views.
- Custom elements.
- Router registration functions.
A package can offer an explicit installer without relying on global discovery:
installAccountRoutes(router, {
basePath: "/account",
});
This keeps integration visible and permits multiple instances or custom paths where the feature supports them.