# How 30 Seconds of Code Manages Content: Inside the Custom ORM Architecture

> Discover how the 30 seconds of code project manages content with its custom ORM architecture. Learn about its in-memory system for registering, querying, and serializing data for efficient content handling.

- Repository: [Angelos Chalaris/30-seconds-of-code](https://github.com/Chalarangelo/30-seconds-of-code)
- Tags: architecture
- Published: 2026-02-25

---

**The 30 seconds of code project uses a lightweight, in-memory ORM-style content management system where all publishable data is registered, queried, and serialized through a central `ContentModel` base class.**

The Chalarangelo/30-seconds-of-code repository powers a popular coding knowledge base without relying on a traditional CMS. Instead, it implements a custom content management layer in JavaScript that treats snippets, collections, and redirects as queryable models. This architecture enables efficient static site generation while maintaining clean separation between data storage and presentation logic.

## The ContentModel Base Class: The Core of 30 Seconds of Code Content Management

All content types in the repository inherit from `ContentModel`, defined in [`src/models/contentModel.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/contentModel.js). This base class provides the ORM-style interface that handles registration, lookup, and common content operations.

### Model Registration and Discovery

Each concrete model registers itself with the base class through a static initializer. The `ContentModel.addContentModel()` method adds the class to a global `Map` called `ContentModel.contentModels`, enabling runtime discovery of all content types.

```javascript
// src/models/contentModel.js
static addContentModel(model) { … }
static searchContentModels(idOrSlug) { … }

```

This registration pattern allows the system to iterate over all content models when resolving URLs or searching for specific content by identifier.

### Slug Resolution and Search

The `ContentModel.searchContentModels()` method normalizes incoming slugs by removing leading and trailing slashes and stripping pagination parameters. It then iterates over all registered models, delegating the actual lookup to each model's `find` method (inherited from the underlying `Model` class).

**Source:** [`ContentModel.searchContentModels`](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/models/contentModel.js#L21-L32)

### Common Content Helpers

The base class supplies shared utilities that all content types use for URL generation and SEO:

- **Slug generation** – `slug` and `slugId` properties derived from the record's `id`
- **Redirect handling** – `allSlugs` uses `Redirects.for(this.url)` to collect historic URLs
- **URL building** – `url` and `fullUrl` combine slugs with the site base URL from `settings`
- **SEO text** – `formattedDescription` and `seoDescription` prepare content for meta tags
- **Serialization** – `serializeAs(name)` selects the appropriate serializer (e.g., `SnippetContextSerializer`)

## Concrete Content Types: Snippet and Collection Models

The repository defines two primary content types that extend `ContentModel`: `Snippet` and `Collection`.

### The Snippet Model

Located in [`src/models/snippet.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/snippet.js), the `Snippet` class represents individual code snippets. It stores metadata including title, description, tags, language, and ranking scores.

Key behaviors include:

- **Content enrichment** – The `enrichedContent` property resolves `<article-embed>` tags by looking up referenced content models via `ContentModel.searchContentModels`
- **SEO title logic** – Automatically prefixes the language name when missing from the title
- **Pagination helpers** – Provides previous/next navigation for snippet journeys

### The Collection Model

Defined in [`src/models/collection.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/collection.js), the `Collection` class groups related snippets (e.g., "Array", "String", "Prompts").

Key capabilities include:

- **Hierarchical data** – Manages `parentId` and `topLevel` properties for nested structures
- **Pagination** – Generates paginated pages via `pages` and `collectionsPages` properties
- **Navigation** – Supplies `siblings` and `rootUrl` helpers for breadcrumb trails
- **Snippet association** – Uses the `CollectionSnippet` bridge model to retrieve associated snippets

Both models inherit slug handling, redirect support, cover image management, and serialization from `ContentModel`.

## Redirect Management for Historical URLs

The repository handles URL changes through a redirect system defined in [`content/redirects.yaml`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/content/redirects.yaml). At application startup, [`src/lib/redirects.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/redirects.js) reads and caches this data:

```javascript
// src/lib/redirects.js
static {
  const data = fs.readFileSync(settings.paths.redirectsYAML, 'utf8');
  this.redirects = yaml.load(data);
}

```

The `Redirects.for(slug)` method traverses the redirect graph backwards, collecting every historic path that maps to the current slug. This set is exposed via `ContentModel.allSlugs`, allowing the site generator to emit proper rewrite rules for web servers.

**Source:** [`Redirects.for`](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/lib/redirects.js#L24-L45)

## Content Serialization for Static Generation

Each model transforms into plain JSON structures for the static site generator through the serialization system. The mapping between model instances and output formats lives in [`src/serializers/serializers.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/serializers/serializers.js).

Models call `serializeAs(name)` to select the appropriate serializer (e.g., `SnippetContextSerializer`). Each serializer implements a `serialize()` method that extracts only the fields needed for a specific view—whether preview cards, full pages, or API responses.

**Source:** [`ContentModel.serializeAs`](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/models/contentModel.js#L19-L27)

## Data Flow: From Bootstrap to Rendered Page

The 30 seconds of code content management system follows a clear pipeline:

1. **Bootstrap** – When the app starts, `ContentModel` registers `Snippet` and `Collection` classes via `addContentModel`
2. **Loading** – Records load from CSV/JSON sources into the in-memory `Model` store
3. **Lookup** – URL requests transform into slugs; `ContentModel.searchContentModels` finds the correct model instance
4. **Enrichment** – The model resolves redirects, cover images, and embedded snippets via `enrichedContent`
5. **Serialization** – The appropriate serializer produces the final payload for page rendering or API response

**Code Example – Fetching a snippet and rendering its embed:**

```javascript
import ContentModel from '#src/models/contentModel.js';

// 1️⃣ Resolve a slug (could be a historic URL)
const slug = '/array/push';
const snippet = ContentModel.searchContentModels(slug);

// 2️⃣ Use the model's helpers
console.log(snippet.title);                 // "Array.push"
console.log(snippet.fullUrl);               // https://30secondsofcode.org/array/push
console.log(snippet.allSlugs);              // ['...old-paths…']

// 3️⃣ Get enriched HTML (embeds other snippets)
const html = snippet.enrichedContent;

// 4️⃣ Serialise for the static site generator
const preview = snippet.preview; // uses SnippetContextSerializer under the hood

```

**Code Example – Generating redirects for the web server:**

```javascript
import Redirects from '#src/lib/redirects.js';
import settings from '#src/config/settings.js';

// Generates a Nginx/Apache rewrite file at build time
Redirects.generate();   // writes to settings.paths.out.redirects

```

**Key Files**

| Role | File | Link |
|------|------|------|
| Base content logic | [`src/models/contentModel.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/contentModel.js) | [contentModel.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/models/contentModel.js) |
| Snippet model | [`src/models/snippet.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/snippet.js) | [snippet.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/models/snippet.js) |
| Collection model | [`src/models/collection.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/collection.js) | [collection.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/models/collection.js) |
| Redirect handling | [`src/lib/redirects.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/redirects.js) | [redirects.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/lib/redirects.js) |
| Serialisers hub | [`src/serializers/serializers.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/serializers/serializers.js) | [serializers.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/serializers/serializers.js) |
| Settings (paths, site URL) | [`src/config/settings.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/config/settings.js) | [settings.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/src/config/settings.js) |

## Summary

- The **30 seconds of code** project implements a custom ORM-style content management system using JavaScript classes rather than a traditional database or CMS.
- **ContentModel** ([`src/models/contentModel.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/contentModel.js)) serves as the abstract base that handles model registration, slug resolution, redirect aggregation, and serialization dispatch.
- Concrete implementations **Snippet** and **Collection** extend the base to provide domain-specific logic for code examples and content grouping.
- **Redirects** ([`src/lib/redirects.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/redirects.js)) are managed via YAML configuration and traversed at runtime to support historic URL patterns.
- The **serialization layer** ([`src/serializers/serializers.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/serializers/serializers.js)) transforms in-memory models into JSON payloads for static site generation, enabling efficient page rendering.

## Frequently Asked Questions

### What is the ContentModel class in 30 seconds of code?

The `ContentModel` class is the abstract base class defined in [`src/models/contentModel.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/models/contentModel.js) that powers the project's ORM-style content management system. It maintains a global registry of all content models via `ContentModel.contentModels`, provides slug normalization through `searchContentModels()`, and supplies common utilities for URL generation, SEO metadata, and serialization dispatch.

### How does 30 seconds of code handle URL redirects?

The project manages historical URLs through a YAML configuration file at [`content/redirects.yaml`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/content/redirects.yaml). At startup, [`src/lib/redirects.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/lib/redirects.js) loads this data into memory. The `Redirects.for(slug)` method traverses the redirect graph backwards to collect all historic paths mapping to a current slug, which `ContentModel` exposes via the `allSlugs` property to generate server rewrite rules.

### What serialization system does 30 seconds of code use?

The repository uses a context-aware serialization system located in [`src/serializers/serializers.js`](https://github.com/Chalarangelo/30-seconds-of-code/blob/main/src/serializers/serializers.js). Each model calls `serializeAs(name)` to select the appropriate serializer (such as `SnippetContextSerializer`), which implements a `serialize()` method to extract only the fields required for specific views—whether for preview cards, full pages, or API responses.

### How are snippets and collections related in the content hierarchy?

`Snippet` and `Collection` are both concrete implementations of `ContentModel` that represent different levels of the content hierarchy. While `Snippet` stores individual code examples with metadata like language and tags, `Collection` groups these snippets into categories (e.g., "Array" or "String") using hierarchical data with `parentId` and `topLevel` properties. The `CollectionSnippet` bridge model associates specific snippets with their parent collections.