{"id":50819170,"url":"https://github.com/avanelsas/bareforge","last_synced_at":"2026-06-13T12:05:53.827Z","repository":{"id":354269279,"uuid":"1222877925","full_name":"avanelsas/bareforge","owner":"avanelsas","description":"Companion visual builder for BareDOM web components. Drag components, declare reactive state, export fully interactive CLJS or JS project","archived":false,"fork":false,"pushed_at":"2026-06-08T10:02:34.000Z","size":735,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-08T11:19:41.694Z","etag":null,"topics":["baredom","clojurescript","drag-and-drop","full-theming","landing-page","mobile-ready","vanilla-js","visual-builder","web-components"],"latest_commit_sha":null,"homepage":"https://avanelsas.github.io/bareforge/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avanelsas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit/2026-04-23-bareforge-audit.md","citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-27T19:50:57.000Z","updated_at":"2026-06-08T10:02:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/avanelsas/bareforge","commit_stats":null,"previous_names":["avanelsas/bareforge"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/avanelsas/bareforge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanelsas%2Fbareforge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanelsas%2Fbareforge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanelsas%2Fbareforge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanelsas%2Fbareforge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avanelsas","download_url":"https://codeload.github.com/avanelsas/bareforge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanelsas%2Fbareforge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34283442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["baredom","clojurescript","drag-and-drop","full-theming","landing-page","mobile-ready","vanilla-js","visual-builder","web-components"],"created_at":"2026-06-13T12:05:49.228Z","updated_at":"2026-06-13T12:05:53.812Z","avatar_url":"https://github.com/avanelsas.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bareforge\n\n\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"public/assets/bareforge_darkmode.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"public/assets/bareforge_lightmode.png\"\u003e\n    \u003cimg alt=\"Project Logo\" src=\"public/assets/bareforge_lightmode.png\" width=\"200\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\nA visual landing-page builder for [BareDOM](https://github.com/avanelsas/baredom).\nThis project offers a drag and drop interface to build a web component based static page and using bindings, records and events can export to a fully interactive, functional extensible codebase in either ClojureScript or JavaScript.\n\n![CI](https://github.com/avanelsas/bareforge/actions/workflows/ci.yml/badge.svg)\n\nBareforge is built in ClojureScript on top of BareDOM's 90 stateless web\ncomponents. The editor chrome itself is made from BareDOM elements —\npalette, inspector, toolbars, layers, modals — dogfooding the library\ninside a real end-user application. The canvas uses a hand-written DOM\nreconciler (no virtual DOM) to stay philosophically aligned with BareDOM.\n\n## Why Bareforge?\n\nLike most Clojure/ClojureScript developers starting out with UIs, I went through the common phases of using Reagent and Re-frame—which are great utilities in their own right. However, as my UIs became larger and more complex, bundle sizes increased, and I found myself spending too much time rebuilding generic, reusable components from scratch.\n\nI started looking for a different approach and discovered Web Components. I built a few, but didn't have the spare time to develop a comprehensive set that could be used in any project. Then AI arrived. While experimenting with Claude Code, I realised that 1 + 1 could be 3. That is how BareDOM, my first open-source project, was born.\n\nI then turned to another aspect of web development and thought about how I could make web components easier in use. I often found myself taking a Figma design and translating it into UI components and code.\n\nI wondered if I could automate some of that and with that the idea for Bareforge was born. I wanted something that would not just deliver a static page. Instead it should allow exporting a complete and interactive CLJS or JS project that can be used for further development. It is still rough around the edges but I hope it brings you joy and usefulness when designing and developing web/landing pages.\n\n## Features\n\n- **Drag-drop canvas** with before / inside / after drop indicators\n- **Inspector** with type-aware editors for every BareDOM component —\n  enums as dropdowns, colors as pickers, booleans as switches, URLs,\n  numbers, and a per-instance CSS-variable editor\n- **Free-form positioning** for decoratives (absolute x/y/w/h) with an\n  8-handle resize overlay and keyboard nudging (arrow keys, 10 px with\n  Shift, coalesced into a single undo step)\n- **Flow resize** handles on non-free elements (E / S / SE only, updating\n  `:width` / `:height` as CSS length strings)\n- **Component-aware snap** on drop — an `x-navbar` lands at the top of\n  the root at full width; an `x-sidebar` does the same; easily extensible\n  via `meta/placement.cljs`\n- **Theme editor** with 8 built-in presets and full per-token overrides\n- **Autosave** to IndexedDB (debounced) plus explicit project files\n  (`.json`) via File Download / File Upload\n- **Project files** are spec-validated on load — malformed payloads are\n  refused rather than silently installed\n- **Four export modes**:\n  - **CDN export** (static snapshot) — one HTML file, loads BareDOM\n    from jsDelivr at runtime (requires internet). Markup only; no\n    reactive state.\n  - **Bundle export** (static snapshot) — a `.zip` with the HTML +\n    a local `vendor/baredom/` folder containing every module the\n    document uses; serve from any static HTTP server offline.\n    Markup only; same contract as CDN export.\n  - **ClojureScript export** (interactive) — a full shadow-cljs\n    project that ships a minimal re-frame subset plus the\n    declarative data-binding layer. Buttons fire actions, fields\n    update state, computed subs recompute. See\n    [`docs/recipes.md`](./docs/recipes.md) for how to build one\n    end-to-end.\n  - **Vanilla JavaScript export** (interactive) — a `.zip` with a\n    tiny reactive store, a hand-written reconciler, and per-group\n    view modules. Same feature parity as the ClojureScript export\n    (template groups, collection fields, the seven computed\n    operations, bindings, triggers, raw-HTML icons) — no\n    framework dependency, plain DOM + ES modules.\n- **Pluggable export system** — the four targets above are\n  built-in plugins under `src/bareforge/export/\u003cname\u003e/`; adding a\n  new one (React, Svelte, your in-house framework) is a manifest\n  + a single `generate` fn. See [`docs/plugins.md`](./docs/plugins.md).\n- **Undo / redo** with 100-step history, including coalesced keyboard\n  nudges (hold arrow → one undo step)\n- **Preview mode** toggle — drops the editor chrome interactions so you\n  can click through the page as a user\n- **Escape to deselect** + full keyboard shortcuts (Cmd-Z / Cmd-Shift-Z /\n  Delete / arrow-key nudge)\n\n## Docs\n\nThe deep-dive content lives in [`docs/`](./docs/) so this README\nstays scannable:\n\n- [`docs/recipes.md`](./docs/recipes.md) — end-to-end walkthrough\n  that builds a filterable product feed with an add-to-cart flow,\n  plus a quick-reference index.\n- [`docs/adding-components.md`](./docs/adding-components.md) —\n  scaffolder recipe for onboarding a new BareDOM component into\n  the palette.\n- [`docs/architecture.md`](./docs/architecture.md) — architecture,\n  data model, rendering pipeline, project layout, and per-component\n  notes for new contributors.\n- [`docs/plugins.md`](./docs/plugins.md) — export plugin authoring\n  guide.\n- [`docs/repl.md`](./docs/repl.md) — editor-connected REPL setup\n  (Calva / CIDER / Cursive) and the recommended dev loop.\n- [`docs/dev-setup.md`](./docs/dev-setup.md) — first-time contributor\n  walkthrough: toolchain, `./scripts/check.sh`, common pitfalls.\n\n## Authoring shortcuts\n\nA set of power-user gestures that make daily editing faster. Every\nkeyboard shortcut lives in a press-`?` cheat sheet; every action is\nreachable through a Cmd-K command palette.\n\n### Multi-select \u0026 bulk ops\n\n- **Shift-click** any node (canvas or Layers panel) to extend the\n  selection. **Drag from empty canvas** for marquee select; hold\n  **Shift** to extend.\n- With multiple nodes selected, the Inspector shows the **shared\n  attributes** across them. Edit a row once, every selected node\n  updates in a single undo step. Mixed values render with a `Mixed`\n  placeholder.\n- **Cmd-D** duplicates (deep-clone with fresh ids); **Cmd-G** wraps\n  the selection in an `x-container` (**Cmd-Shift-G** prompts for\n  `x-grid` / `x-card` / `x-navbar`); **Delete** removes the whole\n  set in one commit.\n- **Cmd-Opt-C / Cmd-Opt-V** copy attributes from the selection and\n  paste them onto another node, filtered to the target tag's\n  supported attrs — a paste from `x-button` onto an `x-card`\n  silently drops `variant` instead of stamping an unknown attr.\n\n### Inspector ergonomics\n\n- **Drag-to-scrub** numeric labels — the `min` / `max` / `step` rows\n  and the free-coord `:layout :x / :y / :w / :h` rows. Drag the\n  label horizontally; hold Shift for ×10 steps. The whole drag is\n  one undo entry.\n- **`var(--x-…)` autocomplete.** Type `var(` into a colour or length\n  field and a native `\u003cdatalist\u003e` surfaces every BareDOM theme\n  token — `--x-color-primary`, `--x-space-md`, `--x-radius-lg`,\n  and so on, sourced from `x-theme` and resolved live by the\n  active preset.\n\n### Discoverability\n\n- **`?`** opens a cheat sheet with every keyboard shortcut and\n  gesture, grouped by category. Built on `x-modal` + `x-typography`\n  so it inherits the live theme preset.\n- **Cmd-K** opens a fuzzy command palette built on\n  `x-command-palette`. Insert any of the 90 BareDOM tags by typing\n  a fragment of the name; toggle the theme editor, the templates\n  panel, preview mode, or the cheat sheet itself — every toolbar\n  action is one keystroke away.\n- **Layers keyboard nav.** Focus the Layers tree, then ↑ / ↓ walk\n  siblings, ← / → step to parent / first child, **Alt+↑ / Alt+↓**\n  reorder within the parent slot.\n- **Palette pattern flyout.** Components with curated variants —\n  `x-button` (primary / secondary / ghost / danger / loading),\n  `x-typography` (h1–h3 / body / caption / code), `x-alert`,\n  `x-badge`, `x-card`, `x-grid` (2-col / 3-col / 4-col / sidebar),\n  and more — show a `▾` caret next to their palette tile. Expand,\n  pick a chip, the component lands pre-styled.\n- **Empty-slot hints.** Empty containers in edit mode show a per-tag\n  prompt — `Drop nav links / actions` inside an empty `x-navbar`,\n  `Drop tiles into the grid` inside an `x-grid`, `Drop x-tab here`\n  inside `x-tabs` — so the next move is always obvious.\n\n## Fields \u0026 bindings\n\nGive a container a **name** and it becomes a component group with its\nown reactive state. Declare typed **fields** on the group (e.g.\n`:cart-count` → number, default `0`); any attribute of any descendant\ncan then be **bound** to a field — a `:read` binding tracks it live\n(the `:text` of an `x-badge` mirrors `:cart-count`), a `:write`\nbinding lets an event trigger update it, and event triggers pick an\noperation from `:increment`, `:decrement`, `:toggle`, `:set`,\n`:clear`. On export, fields become the group's `default-db`, reads\nbecome `rf/reg-sub` + `rf/query`, and event triggers become\n`rf/reg-event` + `rf/dispatch` — a minimal re-frame shape, no React,\nno Reagent.\n\n## Templates\n\nBareforge ships with 8 starter templates that showcase BareDOM's component\nlibrary and modern web design patterns:\n\n| Template | Description |\n|----------|-------------|\n| **SaaS Hero** | Gaussian blur background, navbar, kinetic typography headline, particle button CTAs, and a stats row |\n| **Bento Features** | Section heading with a bento grid of feature cards, including a multi-span highlighted card |\n| **Our Story** | Narrative cards separated by organic dividers — a vertical storytelling layout |\n| **Pricing Table** | Three-tier pricing cards (Starter / Pro / Enterprise) with badges, dividers, and feature lists |\n| **Testimonials** | Grid of customer quote cards with avatars and attributions |\n| **How It Works** | Four-step timeline with labels, titles, and descriptive content |\n| **Contact** | Two-column layout with a form (wrapped in `x-form`) and a contact info card |\n| **Full Landing Page** | Complete multi-section page combining navbar, hero, stats, feature grid, testimonial, and CTA footer with a gaussian blur background |\n\nPick a template from the Templates panel to start with a pre-built\nstructure, then customise content, theme, and layout in the editor.\n\n## Status\n\n**Early alpha.** Feature-complete: 90 BareDOM components in the\npalette, four export plugins at full feature parity (HTML, bundle,\nCLJS, vanilla-JS), nine starter templates, first-run welcome tour,\ndoc-level XSS sanitiser, CSP + SRI on every export. 571 tests / 0\nrelease-build warnings under Closure Advanced. Expect rough edges\non less-common BareDOM components until their augment entries are\nhand-tuned. See [`CHANGELOG.md`](./CHANGELOG.md) for what's in\neach release.\n\n## Relationship to BareDOM\n\nBareforge is a **consumer** of BareDOM, pulled from Clojars as\n`com.github.avanelsas/baredom`. This repository does not modify BareDOM\n— version bumps happen via `deps.edn`.\n\n## Quick start\n\n```bash\n# Install dev dependencies (jszip for bundle export)\nnpm install\n\n# Start dev server on http://localhost:8765\n# Also exposes an nREPL on port 7888 — see docs/repl.md.\nnpx shadow-cljs watch app\n\n# Release build (Closure :advanced)\nnpx shadow-cljs release app\n\n# Tests\nnpx shadow-cljs watch test\n\n# All four PR-readiness gates in one go\n./scripts/check.sh\n```\n\nRequirements: JDK 11+, Node 18+. Contributors should match CI exactly\n(Java 21, Node 20) — see [`docs/dev-setup.md`](./docs/dev-setup.md).\n\n## Philosophy (brief)\n\nEvery edit flows through a pure transform (`doc.ops/*`) before being\ncommitted through the single atom (`bareforge.state/app-state`). The\nreconciler is a one-way function `DOM = f(state)`. Pure zone\n(`doc/`, `meta/`, `export/` serialization, `storage/` serialization)\nis side-effect-free and tested without a browser; effectful zone\n(`render/`, `dnd/`, `ui/`, `state.cljs`) is the only place with DOM\naccess or atom writes. `CLAUDE.md` has the full rule list.\n\n## Contributing\n\nFirst-time contributor? Start with [`docs/dev-setup.md`](./docs/dev-setup.md)\n— toolchain pins, `./scripts/check.sh`, and common pitfalls.\n\nRead `CLAUDE.md` before writing code. It encodes the pure / effectful\nzone boundary, the one-atom rule, spec usage at boundaries, Closure\nAdvanced safety, and the runtime-dependency policy (only BareDOM and\nJSZip).\n\n## License\n\nMIT. See `LICENSE` for the full text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favanelsas%2Fbareforge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favanelsas%2Fbareforge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favanelsas%2Fbareforge/lists"}