> For the complete documentation index, see [llms.txt](https://jscula.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jscula.gitbook.io/docs/structuring-your-codebase.md).

# Structuring your codebase

## 3 Ways to Structure a Codebase When Working with Jscula

When building websites with Jscula, there isn't just one correct way to organize your JavaScript. The best structure depends on the size of your project, how much code you're writing, and how you want to manage scripts across different pages.

I'd teach these three approaches as a progression from beginner to advanced:

1. Plain JavaScript + `onPageLoad()` — start simple.
2. ES Modules + a central `main.js` — organize code into reusable modules.
3. Jscula Auto Load + `loadResources()` — load resources according to the needs of different pages or sections.

These aren't three competing ways to do exactly the same thing. Each solves a different organizational problem.

### At a glance

| Approach                         | Level                 | Best for                                         |
| -------------------------------- | --------------------- | ------------------------------------------------ |
| 1. One JS file + `onPageLoad()`  | Basic                 | Small websites and learning Jscula               |
| 2. ES Modules + `main.js`        | Intermediate          | Growing projects with reusable features          |
| 3. Auto Load + `loadResources()` | Intermediate–Advanced | Multi-page websites with page-specific resources |

The ratings are my practical recommendations, not official Jscula ratings.

### 1. Plain one-file JavaScript + [`onPageLoad()`](/docs/events/onpageload.md)

Basic: The simplest way to get started

Keep the JavaScript for your website in one file. Use Jscula's `onPageLoad(page, callback)` to run the appropriate code when a matching page or route loads.

#### Sample structure

```
my-website/
├── index.html
├── about.html
├── contact.html
├── css/
│   └── style.css
└── js/
    └── app.js
```

#### `index.html`

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Website</title>
</head>
<body>
  <h1>Welcome to my website</h1>
  <button id="welcome-btn">Say hello</button>

  <script src="https://cdn.jsdelivr.net/npm/jscula-core/dist/jscula.min.js"></script>
  <script src="./js/app.js"></script>
</body>
</html>
```

#### `js/app.js`

```javascript
// Runs when the root page matches.
onPageLoad("/", () => {
  $("#welcome-btn").onClick(() => {
    alert("Welcome to my website!");
  });
});

// Runs when the about page matches.
onPageLoad("/about.html", () => {
  console.log("The About page is active.");
});

// Runs when any page under /admin/ matches.
onPageLoad("/admin/*", () => {
  console.log("An admin page is active.");
});
```

The selectors and event handlers here illustrate Jscula-style usage. The important point is that [`onPageLoad()`](/docs/events/onpageload.md) is route-aware: you pass a page or route pattern and a callback. It is not simply a replacement name for `DOMContentLoaded`.

#### How it works

* One file: Your website's JavaScript lives in `app.js`.
* Page-specific behavior: [`onPageLoad()`](/docs/events/onpageload.md) lets you associate behavior with particular routes.
* Easy to learn: Beginners can focus on JavaScript and Jscula without first learning a module system.
* Easy to start, harder to scale: As more features are added, the file can become crowded.

#### When should you use it?

Use this structure for a portfolio, landing page, small business website, simple dashboard, or your first Jscula project.

### 2. ES Modules + a central `main.js`

Intermediate: The modular approach

Separate your code into files based on responsibility. A central `main.js` imports the features it needs and coordinates initialization.

#### Sample structure

```
my-website/
├── index.html
├── about.html
├── css/
│   └── style.css
└── js/
    ├── main.js
    ├── pages/
    │   ├── home.js
    │   └── about.js
    ├── components/
    │   ├── navbar.js
    │   └── modal.js
    └── utils/
        └── formatDate.js
```

Each file has a clear responsibility. You don't have to put navigation, modal logic, date formatting, and page initialization into one giant script.

#### `js/pages/home.js`

```javascript
export function initHomePage() {
  $("#welcome-btn").onClick(() => {
    alert("Welcome home!");
  });
}
```

#### `js/pages/about.js`

```javascript
export function initAboutPage() {
  console.log("About page initialized.");
}
```

#### `js/main.js`

```javascript
import { initHomePage } from "./pages/home.js";
import { initAboutPage } from "./pages/about.js";

// Jscula is loaded separately through the CDN script.
onPageLoad("/", () => {
  initHomePage();
});

onPageLoad("/about.html", () => {
  initAboutPage();
});
```

#### HTML setup

Load Jscula before your module entry point:

```html
<script src="https://cdn.jsdelivr.net/npm/jscula-core/dist/jscula.min.js"></script>
<script type="module" src="./js/main.js"></script>
```

For a production application, verify that the global API is accessible in your chosen module setup. This example uses Jscula's CDN-based global API alongside ES modules for your own application code; it does not assume that the CDN script itself is an ES module.

#### How it works

* `export`: A feature makes its functions available to other files.
* `import`: Another file brings those functions in.
* `main.js`: Acts as the central entry point for initialization.
* Separation of concerns: Each module owns a focused part of the application.

#### When should you use it?

Use this structure when building a dashboard, admin panel, e-commerce frontend, or any application with reusable components and multiple features.

Use it for medium and large projects.

One important distinction: ES modules organize your code and dependencies. They don't automatically decide which page-specific scripts or stylesheets should load. You manage that through your imports, conditional initialization, or another resource-loading strategy.

### 3. Jscula Auto Load + [`loadResources()`](/docs/ajax/loadresources.md)

Intermediate–Advanced: The resource-management approach

Use Jscula's resource-loading configuration to define CSS and JavaScript resources, organize them under keys, and load the resources needed by a particular page or section.

This is the approach that makes direct use of Jscula's [`loadResources()`](/docs/ajax/loadresources.md) feature. Rather than manually writing every script tag into every HTML page, you maintain a resource configuration and load resources using their assigned keys.

#### Sample structure

```
my-website/
├── index.html
├── about.html
├── jscula.config.json //(important)
├── css/
│   ├── global.css
│   ├── home.css
│   └── about.css
└── js/
    ├── shared.js
    ├── home.js
    └── about.js
```

#### `jscula.config.json`

Here's an example configuration based on the documented `css`, `scripts`, and `autoLoad` options:

```json
{
  "autoLoad": false,
  "css": [
    "./css/global.css"
  ],
  "scripts": {
    "home": [
      "./js/home.js"
    ],
    "about": [
      "./js/about.js"
    ]
  }
}
```

The example uses `autoLoad: false` so that keyless resources aren't automatically loaded. The resources under `home` and `about` can be requested explicitly.

#### Loading resources for the current page

```javascript
// Load resources for the home page.
onPageLoad("/", () => {
  loadResources("home");
});

// Load resources for the about page.
onPageLoad("/about.html", () => {
  loadResources("about");
});
```

Include the Jscula script before the application code, as in the first example. Your setup also needs to make the configuration available to Jscula as documented for [`loadResources()`](/docs/ajax/loadresources.md).

#### Loading multiple resource groups

<pre class="language-html"><code class="lang-html">&#x3C;script>
<strong>    loadResources(["home", "about"]);
</strong>&#x3C;/script>
</code></pre>

Use this when you intentionally need both resource groups. You generally wouldn't load both groups on every page if they contain unrelated page-specific behavior.

#### How it works

* Central configuration: CSS and JavaScript resources are defined in [`jscula.config.json`](/docs/ajax/loadresources.md).
* Named resource groups: Keys such as `home` and `about` identify groups of scripts.
* Explicit loading: Call `loadResources("home")` when you need that group.
* Optional automatic loading: Jscula's `autoLoad` setting controls automatic loading of keyless resources.
* More control over resource loading: The configuration supports additional script attributes, including `defer`, `async`, `type`, `id`, and placement options.

#### When should you use it?

Use this structure when building a multi-page application where different pages need different scripts or styles, such as web applications, online platforms, admin dashboard, or online store, etc..

For a tiny website, the extra configuration may not be worth it.

Important: `loadResources()` is a resource loader, not a substitute for modular architecture. It can load resources by key, but it does not inherently give you the import/export dependency management that ES modules provide.

### Which structure should you recommend to developers?

| Question                                                                       | Best choice                                                  |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------ |
| I'm learning JavaScript and Jscula.                                            | One file + [`onPageLoad()`](/docs/events/onpageload.md)      |
| My code is growing and I want reusable features.                               | ES Modules + `main.js`                                       |
| My pages need different scripts and styles.                                    | Auto Load + [`loadResources()`](/docs/ajax/loadresources.md) |
| My project is large and needs both modularity and controlled resource loading. | Combine ES Modules with Auto Load where appropriate          |

### Best practices for all three approaches

1. Keep responsibilities clear. Avoid mixing every feature, page handler, and utility into one enormous function.
2. Use page-aware initialization. Put page-specific behavior inside the appropriate `onPageLoad(page, callback)` handler rather than running it indiscriminately across the entire website.
3. Avoid duplicate initialization. Make sure the same event handlers aren't attached repeatedly when your application initializes.
4. Keep shared code reusable. Navigation, formatting helpers, and common UI behavior shouldn't need to be rewritten for every page.
5. Load only what you need. With Auto Load, separate shared resources from page-specific resource groups.
6. Don't overengineer. A beginner's project doesn't need a complex directory tree just to display a few buttons and headings.
