@cnuebred/frontforge v0.1.3
FrontForge

FrontForge is a minimalist TypeScript-based frontend framework that allows you to describe your entire HTML structure, styles, and logic in code - and compile it into a complete, standalone HTML file. Ideal for generating simple UI apps or static pages directly from TypeScript.
This project was created out of pure passion by a beginner developer who strongly believes in simplicity, transparency, and minimal dependencies. FrontForge is intentionally built to stay lean, with no heavy abstractions or runtime overhead โ just TypeScript and the browser DOM.
โจ Features
- ๐งฑ Declarative UI construction with
WidgetandContainerWidget - ๐ฏ Reactive state with
Pocket(based on Proxy) - ๐ฆ Auto HTML/JS/CSS bundling with
ForgeBundle - โ๏ธ Easy layout utilities via
Flex()andGrid() - ๐ฑ๏ธ Simple event handling with
.event() - ๐ Markdown-style inline content support
- ๐จ Minimal dependencies, zero-runtime abstraction
๐ฆ Installation
npm install @cnuebred/frontforgeRequires Node.js (LTS recommended) and TypeScript.
๐ Quick Example
// >>> main.ts
import { Widget, ContainerWidget, ForgeBundle } from "@cnuebred/frontforge";
// Create UI elements
const header = new Widget("h1.title", "Welcome to FrontForge");
const button = new Widget("button", "Click me");
// React to click event
button.event("click", () => {
header.value = "Button clicked!";
header.render();
});
// Group in a container and attach to DOM
const container = new ContainerWidget("div");
container.add(header).add(button);
container.hook("body");
// >>> end of main.ts
import { ForgeBundle } from "@cnuebred/frontforge";
// Bundle and export as HTML
const bundle = new ForgeBundle();
await bundle.script("./main.ts");
await bundle.style("./style.scss");
bundle.head.title("My App");
bundle.build("index", "./dist");๐งฐ API Overview
Widget
const w = new Widget("p.text", "Hello");
w.attribute = { id: "my-id", style: "color: red;" };
w.value = "**Bold** content";
w.event("click", () => alert("clicked"));
w.render();ContainerWidget
const c = new ContainerWidget("div");
c.add(new Widget("span", "Child 1"));
c.add(new Widget("span", "Child 2"));
c.hook("body");Pocket (reactive state)
import { Pocket } from "@cnuebred/frontforge";
const p = new Pocket({ count: 0 });
const state = p.target;
p.set_setter_callback(({ property, new_value }) => {
console.log(`${property} changed to ${new_value}`);
});
state.count++; // triggers the callbackFlex / Grid Layouts
import { Flex, flex_direction_e, flex_justify_e, Widget } from "@cnuebred/frontforge";
const row = Flex([
new Widget("div.box", "A"),
new Widget("div.box", "B"),
], {
direction: flex_direction_e.row,
justify_content: flex_justify_e.space_between,
height: 200
});
row.hook("body");๐ ๏ธ Build & Bundle
Use ForgeBundle to compile your app to a standalone .html file with embedded styles and JS.
const bundle = new ForgeBundle();
await bundle.script("./src/app.ts");
await bundle.style("./src/styles.scss");
bundle.head.title("My Static Page");
bundle.head.meta({ name: "viewport", content: "width=device-width, initial-scale=1" });
bundle.build("index", "./dist");๐ง Requirements
- Node.js (v16+ recommended)
- TypeScript
- Works in browser environments
- Uses:
esbuild,sass,crypto, and modern ES features
๐งช Playground / Test
You can experiment with widgets like this:
const counter = new Widget("h2", () => `Count: ${state.count}`);
const button = new Widget("button", "Increment");
button.event("click", () => { state.count++ });
const layout = Flex([counter, button]);
layout.hook("body");๐ Roadmap
- Component abstraction
- Data binding helpers
- Dev server with hot reload
๐โโ๏ธ Author
Made with โค๏ธ by Cube (@cnuebred)
Feedback, issues, or contributions are welcome!
10 months ago
10 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago