Project Directory Structure
Relevant source files
The following files were used as context for generating this wiki page:
- deployment/README.md
- WARP.md
- README.md
- client/landing/routes/compare/memotronWheel.ts
- client/landing/memotron.io/compare/memotronWheel.ts
- client/products/memotron/capture/capture.store.ts
- test-setup.js
- client/cx/contemporaries/notion.json
- client/cx/contemporaries/obsidian.json
- client/landing/shared/faqs.data.ts
The Nucleus project is organized as a monorepo, managed by Turborepo, to house the codebase for a suite of personal productivity and well-being tools. This structure facilitates code sharing and streamlined development across multiple applications, including Memotron, Pointron, and the Nucleus super app. The frontend is built with SvelteKit and TailwindCSS, while the backend utilizes Node.js.
This architecture separates concerns into distinct top-level directories, handling client-facing applications, server-side logic, shared packages, and deployment configurations.
High-Level Overview
The monorepo is divided into several key directories, each with a specific responsibility. The diagram below illustrates the main components of the repository structure.
This diagram shows the primary directories within the monorepo and their relationships.
Sources: WARP.md:12-22
Top-Level Directories
The root of the project contains directories that logically segment the codebase.
| Directory | Description |
|---|---|
client/ | Contains all frontend code and product-specific implementations. |
packages/ | Holds shared libraries used across different parts of the monorepo. |
server/ | Contains the backend API and database logic. |
shared/ | Stores code (like types and utils) shared between the client/ and server/. |
deployment/ | Includes deployment configurations and related documentation. |
tests/ | A dedicated directory for test files. |
Sources: WARP.md:12-22
client/ Directory
The client/ directory is the heart of the frontend, containing the code for all user-facing applications and shared UI components.
Sources: WARP.md:13-18
This diagram illustrates the internal structure of the client/ directory.
Sources: WARP.md:13-18, test-setup.js:40-42
Product Applications
The client/products/ subdirectory contains the individual SvelteKit applications. A setup verification script confirms the existence of these product directories.
The following products are present:
nucleusmemotronpointrongathery
Sources: WARP.md:14, test-setup.js:40-54
Shared Frontend Modules
The client/ directory also contains modules shared across the different product frontends:
components/: Shared UI components.elements/: Basic, foundational UI elements.stores/: Svelte stores for state management.utils/: Utility functions for the client-side.cx/: Contains data related to competitor analysis, such as JSON files for Notion and Obsidian.landing/: Code for product landing pages, including routes and shared data like FAQs.
Sources: WARP.md:15-18, client/cx/contemporaries/notion.json, client/landing/shared/faqs.data.ts
packages/ Directory
The packages/ directory contains shared libraries that can be used by both client-side and server-side applications. This promotes code reuse and consistency. The workspace setup script verifies the presence of these packages.
| Package | Description |
|---|---|
components | Reusable UI components. |
elements | Basic UI elements. |
types | Shared TypeScript types and interfaces. |
utils | Common utility functions. |
stores | Shared Svelte stores. |
actions | Reusable Svelte actions. |
static | Static assets. |
Sources: WARP.md:19, test-setup.js:25-38
server/ and shared/ Directories
The backend logic is separated into the server/ directory, which handles the API and database interactions. To maintain consistency and avoid code duplication between the frontend and backend, a shared/ directory is used. It contains common code, such as type definitions and utility functions, that can be imported by both client/ and server/ applications.
This flow shows how both client and server applications consume code from the shared directory.
Sources: WARP.md:20-21, client/products/memotron/capture/capture.store.ts:2-31
An example of this interaction can be seen in the import statements within a client-side store, which pulls utilities from the shared directory:
// client/products/memotron/capture/capture.store.ts
import {
generateMiniRandomId,
generateSimpleRandomId
} from "$lib/shared/utils/crypto.utils";
import { isValidArrayWithData } from "$lib/shared/utils/obj.utils";
import { isValidString } from "$lib/shared/utils/text.utils";
Sources: client/products/memotron/capture/capture.store.ts:50-53
deployment/ Directory
This directory holds configurations and instructions for deploying the applications. The project supports self-hosting for the frontend-only version of the apps. To deploy an app, specific environment variables must be set.
Sources: WARP.md:22, README.md:32-41
Deployment Configuration
To deploy a specific product, the following environment variables are required:
VITE_PRODUCT={{memotron | pointron | nucleus }}
VITE_STATIC_URL=https://cdn.21n.co
Sources: README.md:37-40
Workspace Verification
The repository includes a Node.js script, test-setup.js, to programmatically verify that the monorepo structure is correctly configured. This script checks for the existence of key directories, such as the product apps within client/products/ and the shared libraries in packages/.
The following snippet from the script demonstrates how it validates the presence of product application directories and their package.json files.
// test-setup.js
console.log('\n🏗️ Checking product apps...');
const products = ['nucleus', 'memotron', 'gathery', 'pointron'];
products.forEach(product => {
try {
// Validate product name to prevent malicious input
if (product.includes('..') || product.includes('/') || product.includes('\\')) {
console.log(` ❌ ${product} (invalid product name)`);
return;
}
const productPath = validatePath(path.join('client', 'products', product));
const exists = fs.existsSync(productPath);
const packageJsonPath = validatePath(path.join('client', 'products', product, 'package.json'));
const hasPackageJson = fs.existsSync(packageJsonPath);
console.log(` ${exists ? '✅' : '❌'} ${product} ${hasPackageJson ? '(has package.json)' : '(missing package.json)'}`);
} catch (error) {
console.log(` ❌ ${product} (path validation error)`);
}
});
Sources: test-setup.js:40-56
Conclusion
The Nucleus project's directory structure is a well-organized monorepo that effectively manages multiple related applications. By leveraging Turborepo and a logical separation of concerns into client, server, packages, and shared directories, the architecture promotes code reuse, maintainability, and streamlined development. This setup is crucial for efficiently building and scaling the suite of productivity tools offered by 21n.org.
Sources: WARP.md