# Tutorial 1: Getting Started ## What You'll Build By the end of this tutorial, you'll have a working TypeScript project that renders a simple message using j-templates. You'll understand the framework's core philosophy and have your development environment ready. **Final Result:** A browser page displaying "Tutorial 1: Getting Started" with styled content ## Prerequisites - **TypeScript knowledge** - You should understand classes, interfaces, and type annotations - **Node.js 16+** - For running Vite dev server - **A code editor** - VS Code recommended ## Learning Objectives - Understand what j-templates is and when to use it - Set up a TypeScript project with j-templates - Create virtual nodes with DOM functions - Render to the DOM with `Component.Attach()` - Understand the component lifecycle at a high level --- ## Step 1: What is j-templates? j-templates is a **lightweight, TypeScript-first UI framework** that focuses on: - **TypeScript classes** - Components are plain TypeScript classes - **Reactive state** - Automatic UI updates when data changes - **Composition over inheritance** - Build complex UIs from simple components - **Minimal boilerplate** - No decorators required for basic usage - **Zero runtime dependencies** - No React, Vue, or Angular needed ### When to Use j-templates **Good for:** - Small to medium applications - Teams comfortable with TypeScript - Learning reactive UI patterns - Projects wanting minimal abstraction **Not ideal for:** - Massive enterprise apps requiring extensive ecosystems - Projects needing pre-built component libraries - Teams preferring JSX/TSX syntax --- ## Step 2: Set Up Your Project ### Initialize the Project ```bash # Create project folder mkdir tutorial-1 cd tutorial-1 # Initialize npm project npm init -y # Install j-templates (version 7.0.75+) npm install j-templates@^7.0.75 # Install TypeScript npm install --save-dev typescript # Install Vite (build tool and dev server) npm install --save-dev vite ``` ### Configure TypeScript Create `tsconfig.json`: ```json { "compilerOptions": { "target": "ES2020", "module": "ES2020", "moduleResolution": "bundler", "strict": true, "experimentalDecorators": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"] } ``` ### Create Folder Structure ``` tutorial-1/ ├── src/ │ └── app.ts # Your TypeScript code ├── index.html # HTML entry point (at root) ├── package.json ├── tsconfig.json └── vite.config.js # Vite configuration ``` Create the folder: ```bash mkdir src ``` ### Configure Vite Create `vite.config.js`: ```javascript import { defineConfig } from "vite"; export default defineConfig({ build: { sourcemap: true, rollupOptions: { // Exclude jsdom from bundling // j-templates has jsdom as a devDependency for testing external: ["jsdom"], }, }, }); ``` **Why this is needed:** j-templates has `jsdom` as a devDependency for testing. If you're running the tutorial examples from within the j-templates repository, Node.js module resolution may find jsdom in the root `node_modules` folder. The `external` configuration tells Vite to skip bundling it. **In a standalone project** (outside the j-templates repo), you typically won't need this configuration because jsdom won't exist in your dependency tree. --- ## Step 3: Create Your First Virtual Node ### Understanding Virtual Nodes j-templates uses **virtual nodes (vNodes)** - lightweight JavaScript objects that represent DOM elements. Instead of writing HTML, you write JavaScript that creates these nodes. ### The DOM Element Functions j-templates provides functions for every HTML element, imported from `j-templates/DOM`: ```typescript import { div, h1, span } from "j-templates/DOM"; ``` These functions create vNodes: ```typescript div({}, () => "Hello") // Creates a
Hello
h1({}, () => "Title") // Creates a

Title

span({}, () => "Text") // Creates a Text ``` ### Creating Nested Elements You can nest vNodes by passing an array as the children: ```typescript const content = div({}, () => [ h1({}, () => "Tutorial 1"), div({}, () => "Hello, j-templates!") ]); ``` **Important:** The array becomes the *children* of the parent div. `Component.Attach()` itself takes a **single vNode**, not an array of vNodes. --- ## Step 4: Write Your Code Create `src/app.ts`: ```typescript import { Component } from "j-templates"; import { div, h1, span } from "j-templates/DOM"; // Create nested vNodes const content = div({}, () => [ h1({}, () => "Tutorial 1: Getting Started"), div({ props: { className: "container" } }, () => [ span({}, () => "Hello, "), span({ props: { style: "color: blue;" } }, () => "j-templates!"), span({}, () => " This is your first virtual node.") ]) ]); // Get the root element and attach the vNode const app = document.getElementById("app")!; Component.Attach(app, content); ``` **What's happening:** 1. **Import** - We bring in `Component` and DOM functions from j-templates 2. **Create vNode** - `div({}, () => [...])` creates a virtual div with children 3. **Attach** - `Component.Attach()` renders the vNode into the real DOM --- ## Step 5: Create the HTML Entry Point Create `index.html` at the project root: ```html Tutorial 1: Getting Started

Tutorial 1: Getting Started

``` --- ## Step 6: Run the Development Server ```bash # Start Vite dev server npm run dev ``` Vite will start a development server (usually at `http://localhost:5173`). Open that URL in your browser. Open `http://localhost:8080` in your browser. You should see: ``` Tutorial 1: Getting Started Hello, j-templates! This is your first virtual node. ``` ### Inspect the DOM Right-click and select "Inspect" to see what was created: ```html

Tutorial 1: Getting Started

Hello, j-templates! This is your first virtual node.
``` j-templates created real DOM elements from our virtual nodes! --- ## Step 7: Experiment Before moving on, try these exercises: ### Exercise 1: Change the Text Modify the message in `src/app.ts`: ```typescript h1({}, () => "My First j-templates App") ``` ### Exercise 2: Add More Elements Create a paragraph element: ```typescript import { p } from "j-templates/DOM"; const content = div({}, () => [ h1({}, () => "Tutorial 1"), p({}, () => "This is a paragraph."), div({}, () => "More content") ]); ``` ### Exercise 3: Add More Styling Use the `props` parameter for inline styles: ```typescript div({ props: { style: "background: #f0f0f0; padding: 10px; border-radius: 4px;" } }, () => "Styled content") ``` ### Exercise 4: Nest Deeper Create a more complex structure: ```typescript const content = div({}, () => [ h1({}, () => "Header"), div({ props: { className: "section" } }, () => [ h1({}, () => "Section Title"), div({}, () => [ span({}, () => "Item 1"), span({}, () => "Item 2"), span({}, () => "Item 3") ]) ]) ]); ``` --- ## Common Issues ### "Cannot find module 'j-templates'" **Solution:** Make sure j-templates is installed: ```bash npm install j-templates ``` ### TypeScript errors in editor **Solution:** Make sure your editor has TypeScript extension installed and `tsconfig.json` is properly configured. ### Nothing appears on the page **Check:** 1. Browser console for errors (F12 → Console) 2. The `#app` element exists in your HTML 3. Vite dev server is running: `npm run dev` 4. The script tag in HTML points to `/src/app.ts` --- ## What You Learned - **j-templates** is a TypeScript-first UI framework - **Virtual nodes** are JavaScript objects representing DOM elements - **DOM functions** like `div()` create virtual nodes - **Component.Attach()** renders a single vNode to the real DOM - **Arrays as children** - You can pass arrays to DOM functions for nested elements --- ## Next Steps In [Tutorial 2: Your First Component](./02-your-first-component.md), you'll: - Create a proper component class - Understand the `Template()` method - Learn about component lifecycle - Build a reusable greeting component --- ## Further Reading - [Components](../patterns/01-components.md) - Deep dive into components - [Templates & Data](../patterns/03-templates-and-data.md) - All about DOM functions - [j-templates README](../../README.md) - Official documentation