9 ms·
Show HN: Dagger.js – A buildless, runtime-only JavaScript micro-framework
TL;DR: dagger.js is a buildless, runtime-only micro-framework that plays nicely with native Web Components. It uses HTML-first directives (e.g. +click, +load) so you can ship a page by dropping a single <script> from a CDN—no bundlers, no compile step.
Why I built it
Modern stacks are powerful but often heavy: bundlers, compile steps, framework DSLs, local CLIs. For internal tools, small apps, and edge/serverless deployments, I wanted something you can view-source, paste into a page, and ship.
What it is:
Runtime-only: no build or VDOM compile; hydrate behaviors directly on HTML.
HTML directives: e.g. +click, lifecycle +load / +loaded / +unload / +unloaded.
Zero APIs: dagger.js works in pure declarative mode, modules and directives provide everything you need to build your application.
Web-Components-first: works alongside Custom Elements; keep concerns local.
Distributed modules: load small, focused script modules via CDN.
Progressive enhancement: the page renders without a build step.
Use cases:
Admin panels & dashboards that don’t warrant a full toolchain
Embed widgets, docs-sites with interactive bits
Edge/serverless apps where cold start and simplicity matter
Links
GitHub: https://github.com/dagger8224/dagger.js https://github.com/dagger8224/dagger.js
Docs/Guide: https://daggerjs.org https://daggerjs.org
Examples: https://codepen.io/dagger8224/pens https://codepen.io/dagger8224/pens
I’d love feedback on edge-cases, and where it breaks. Happy to answer tough questions here.
- TonyPeakman 1y agothanks for taking a look! Positioning: Think Alpine/Vue-like ergonomics but no build and WC-first. Size & perf: Focus is on simplicity and startup latency over framework features. I’m not posting synthetic benchmarks; if you have a real page you want me to try, I’ll profile it and share results. Interop: Works with native Custom Elements. I’m preparing examples with Shoelace/FAST. Security: Directives are sandboxed; no eval. If you spot an injection risk, please open an issue and I’ll patch quickly. Limitations: Complex state management, SSR/streaming, and huge SPA routing aren’t first goals. License: MIT. Contrib: Issues and small PRs welcome (docs, examples, tests especially). I’ll stay in the thread to answer questions and incorporate feedback into the docs.
- xupybd 1y agoWebsite looks dead. I get Godaddy domain parking.
- pylotlight 1y agoworked for me. See also: https://github.com/dagger8224/dagger.js https://github.com/dagger8224/dagger.js
- mdaniel 1y agoI'd guess people are getting different results because of the varying A records https://dns.google/query?name=daggerjs.org https://dns.google/query?name=daggerjs.org https://www.whois.com/whois/3.33.130.190 https://www.whois.com/whois/3.33.130.190 and https://www.whois.com/whois/15.197.148.33 https://www.whois.com/whois/15.197.148.33 are AWS https://www.whois.com/whois/185.199.109.153 https://www.whois.com/whois/185.199.109.153 and similar are GitHub and is almost certainly this repo https://github.com/dagger8224/dagger8224.github.io/blob/main/CNAME https://github.com/dagger8224/dagger8224.github.io/blob/main...
- xupybd 1y agoIt's working now
- chrismorgan 1y agoNo, it’s still broken. DNS is offering six choices, two of which are broken.
- TonyPeakman 1y agoI removed the broken A record, and it should work normally.
- TonyPeakman 1y agoGood catch — thanks for digging into that. You’re right: the domain still has a mix of A records (AWS + GitHub Pages), which explains why some people see different results. I have removed the broken A records and the site works normally now. Appreciate the pointers and links
- malfist 1y agoDagger is also a compile time java dependency injection framework
- mdaniel 1y agoAnd a very cool CI toolkit https://github.com/dagger/dagger https://github.com/dagger/dagger (Apache 2) Link to the DI mentioned by the parent comment https://github.com/google/dagger https://github.com/google/dagger (also Apache 2)
- patates 1y agoWas about to say that it's also a lightweight orm for .net, but apparently that's called dapper and I could swear it was dagger.
- throwaway290 1y agoDagger is also a well known framework/runtime for task pipelines (dagger.io)
- TonyPeakman 1y agoRight — there’s also the dagger DI framework in the Java ecosystem. To avoid confusion: this project is dagger.js, a small runtime-only JavaScript library for HTML/Web Components. Totally unrelated to the Java DI framework other than sharing the name
- deleted 1y ago[deleted]
- mkoryak 1y agoSeems neat. I wouldn't use it for personal stuff because I'd be afraid of getting locked into a framework that might not exist next year. Once this project is about a year old, if it still has any commits, then I'd consider it.
- Arch-TK 1y agoWhat is the risk here? Are you worried that in a year it will be missing a feature you want? It's client side javascript, aside from DOM based XSS (which if reported, you can probably fix yourself), there isn't much to worry about from the security perspective. The web doesn't normally deprecate things so it's probably going to work in a year too. This is a tiny project which already requires that you know JavaScript, so you can't even claim that you can't maintain it because you don't know the implementation language. It doesn't depend on some build step (which often is the thing that breaks after a year).
- TonyPeakman 1y agoExactly — that’s a good way to frame it. One of the reasons I kept Dagger.js tiny and runtime-only was to minimize those risks: no exotic build chain that might break, and nothing beyond plain JS/HTML that the web already guarantees to keep working. HTML + Web Components + a few attributes. That’s about as low-lock-in as a framework can get.
- mkoryak 1y agoIve done this before, I have used a bespoke micro framework to build a webpage. A couple of years later I wanted to update it, but discovered that I couldnt do it because of a bug in this framework and the framework also didnt exist anymore. I could fix the bug myself by reading all their code, or I could start over and use something that would still exist next year. Also, have you read the dagger.js code? https://github.com/dagger8224/dagger.js/blob/main/src/dagger.js https://github.com/dagger8224/dagger.js/blob/main/src/dagger... Its written like the developer has a limited supply of lines of code. No comments, ton of declarations on the same line, and lines that run longer than most widescreen monitors. Its all super compact and dense. I would not want to try to fix a bug here. Suggestion: Add a build step that runs before your code is published to npm so that you can have readable source AND small source.
- mdaniel 1y agoWhat are the criteria for $ interpolation? Is it everywhere? <div class="text"> ${ winner ? 'Wins' : 'Draw' }! </div>
- TonyPeakman 1y agoIn dagger.js interpolation is scoped to attributes and text nodes — anywhere you put ${…} inside the HTML markup, the expression is evaluated against the current directive scope. In your sample code, winner is looked up from the nearest +load directive context. Interpolation isn’t “everywhere” JS-style, it’s only applied to the DOM text/attribute content that Dagger processes. Actually it's standard string template in JS. You may also use the text directive instead to avoid using inline expression: <div class="text" text="`${ winner ? 'Wins' : 'Draw' }!`"> </div>
- nivethan 1y agoIs this aimed at being in the same role as petite-vue and alpinejs? They also don't have a build step. I've started to think something like petite-vue and twind would let you build small internal tools quickly, there are some major downsides to it which is why I haven't committed yet.
- mythz 1y agoUsing the full vue.js doesn't have a build step either. I started out developing UIs using petite-vue, unfortunately ended up rewriting it to use full Vue.js after running into too many of its limitations and issues, which given that it's abandon-ware wont ever be resolved. As such I'd strongly recommend against starting projects with PetiteVue and just use the ESM build of Vue.js which also doesn't require a build step, has the full feature-set, is actively used and maintained, etc. Either way developing Web Apps (using Vue) without a build step using JS Modules is now my preference which I've written about in my Simple, Modern JavaScript post [1] [1] https://servicestack.net/posts/javascript https://servicestack.net/posts/javascript
- zelphirkalt 1y agoIf I had to use one of these modern JS frameworks, I think Vue without build step would be one of the candidates. No shitty webpack configuring, no minimizer, no bundler, no friggin uglyfier, no juggling modules. None of the crap, just write your JS and serve the script, done.
- TonyPeakman 1y agoTotally agree — the ESM build of Vue gives you a great “no-bundler” experience with a full framework behind it. dagger.js sits in the same no-build space, but deliberately strips it down even further: no VDOM, no reactive system, no SFCs. Just HTML with attributes like +click / +load, and it plays nicely with native Web Components. The trade-off is fewer features, but also less surface area and almost nothing to configure. So if Vue ESM is “full-featured without the tooling overhead,” dagger.js is more like “minimal glue you can drop in via <script> when you want to stay as close to plain HTML/JS as possible.”
- taosx 1y agoI’d actually love to see something that goes in the opposite direction, highly optimized and compiled, where the result is as small, fast, and efficient as possible. I get that a lot of people dislike compilation, but once I have the CI set upI never found build steps to be a problem for me. Some time ago while I was experimenting with writing Debian benchmarks[0], I found that by completely avoiding strings, using Uint8Arrays, and manually managing bounds/memory, I could squeeze out performance that almost made you forget you were writing JavaScript. I never ended up submitting a PR, but it was pretty eye-opening. At one point I went into a rabbit hole and tried to build something similar on my own, but it got complicated very quickly given my limited compiler knowledge. That’s why I always thought Prepack[1] was such a cool idea. [0] https://benchmarksgame-team.pages.debian.net/benchmarksgame/index.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... [1] https://github.com/facebookarchive/prepack https://github.com/facebookarchive/prepack
- harrygeez 1y agoI’m in a similar boat like you. I would love for a React-like library that compiles down to direct JavaScript DOM transforms. Of course Svelte exists but I don’t want to mark what is reactive or not and I can’t go back to html templates after using typed JSX. Also I don’t really like the “island” like template syntax of Vue, Svelte, etc
- jeswin 1y agoIf what you're looking for is JSX and TypeScript (but without magic or reactivity), there's something I wrote here: https://webjsx.org https://webjsx.org
- TonyPeakman 1y agoThat's pretty cool.
- bytehowl 1y agoIsn't that actually SolidJS? https://solidjs.com https://solidjs.com
- wffurr 1y agoSeems like it’s been a while since a new JS framework landed on the front page.
- ivape 1y agoThe last decade gave us enough JavaScript for a lifetime.
- Nickersf 1y agoExactly, we also have to think about support and maintenance when building and shipping products. It's always nice to play with new things to keep the learning fresh and see what people are up to. I started with php and .NET Framework ASP and in the early-mid 2010's when the reactive JS frameworks started coming around I just never found my jive with them and just started working at C#/.NET shops and am using Blazor Server now. For my domain of web application development the .NET web application ecosystem works great. Looking at the dagger.js docs and examples found myself thinking, this is more Java(SCRIPT) development. It's going to inherit the same issues as JavaScript (weak typing, no runtime reflection, no binary build output, locked into vendor interpreters with mixed feature support), and that's not mentioning all the oddities with the way object prototypes are implemented and interact with each other. I think the ambition and result of the project are amiable. The author did good work, but it's good work on a thing we need less of in my opinion.
- TonyPeakman 1y agoReally appreciate you taking the time to look through the docs and write such a thoughtful comment. You’re right — JavaScript carries a lot of quirks and limitations that aren’t going away, and if you’re building full-scale business apps in the .NET ecosystem, Blazor is a very natural fit. dagger.js isn’t trying to compete with that class of frameworks. The goal is much narrower: keep a build-free, HTML-first option around for cases where shipping something lightweight, inspectable, and easy to embed is more important than squeezing out type safety or runtime guarantees. I completely agree that we don’t need everybody moving deeper into JS just for the sake of it. But I do think there’s value in keeping a spectrum of tools alive — from strongly-typed/.NET style systems to small runtime-only JS libraries — so developers can pick the right trade-off for their domain. Thanks again for the honest feedback; it helps clarify where this approach makes sense (and where it doesn’t).
- copypaper 1y ago> daggerjs.org is parked free, courtesy of GoDaddy.com I think your site broke? Also, I'd scoop up daggerjs.com while you're at it.
- TonyPeakman 1y agoThanks for reporting this issue, it's fixed now. Welcome back to scoop up dagger.js :)
- jerawaj740 1y agoi don't know why i read it as DangerJs hahhahahhahahah
- TonyPeakman 1y agohaha, it's sharp but not dangerous :}
- omtinez 1y agoNice work! I'm also a fan of the runtime only frameworks. They might not be as efficient as the compiled counterparts on paper, but in my experience the performance loss is almost negligible compared to the rest of the stack. Shameless plug to my own runtime (and compile) micro framework: https://github.com/fresho-dev/mancha https://github.com/fresho-dev/mancha
- TonyPeakman 1y agoThanks! Totally agree — in most real-world apps the “runtime overhead” ends up dwarfed by everything else in the stack, so the build-free ergonomics can be a bigger win. And nice, Mancha looks cool — I’ll give it a read and star. It looks similar with dagger in some features, for instance, mancha uses :data to create scope while dagger uses +load directive. Always great to see other takes on the runtime/compile spectrum; I think having multiple approaches out there is healthy for the ecosystem!
- pyrolistical 1y agoI don’t get it. The native js Dom api has a lot of sharp edges but do people hate it that much abstract away from it? Personally I rather have zero runtime code along side zero build by learning truly native js dom
- zdragnar 1y agoThree reasons spring to mind: 1- the DOM APIs are very verbose, excepting perhaps replacing chunks by setting innerHTML, but 2- manual DOM manipulations aren't composable without also using web components 3- naive manual DOM manipulation can potentially be slow by way of triggering needless layouts/repaints or inefficient use of the APIs Web components didn't exist when the major frameworks came about, and the ones before them handled composition rather poorly if at all (such as backbone). Angular, ember, react and company all sought to provide a cohesive story for code reuse and composition. Many had their own performance stories, though it was always a secondary concern to everything else. I've done a bit of everything, including pure vanilla JS, just jQuery, vanilla + web components, all the way up to next, ember, angularjs and angular, and more. If you're building a web site, vanilla JS is fine. If you're building a web "app", you'll pretty quickly appreciate what a framework can bring to the table. If you don't, you'll also quickly find yourself building your own mini framework and runtime to manage things.
- TonyPeakman 1y agoWell put — that lines up with how I see the ecosystem too. For small sites, vanilla JS is fine; once you move toward “app,” you either reach for a framework or start reinventing bits of one yourself. dagger.js is basically me leaning into that middle ground: accept the verbosity/sharp edges of the DOM, but try to smooth just enough of them with directives (+click, +load, interpolation) so you don’t accidentally start building your own mini framework. It stays runtime-only, works directly with Web Components for composition, and tries not to hide what’s really happening under the hood. So it’s not aiming to replace React/Angular, more to give people a lightweight option before they hit the point where those make sense.
- TonyPeakman 1y ago
- KarlIsIsComing 1y ago[dead]
- leke 1y agoBuildless! I'm already interested.
- TonyPeakman 1y agoGlad to hear that! Buildless is the whole idea — drop in a <script>, wire up a few +click / +load attributes, and you’re up and running. The goal is to keep things simple and view-source-able without needing a bundler or toolchain.
- efilife 1y agowhy is svelte marked as non client side on your website?
- TonyPeakman 1y agoAs a frontend framework, Svelte apps absolutely run in the browser.However, Svelte relies on a compile step: your authoring code is compiled ahead of time into efficient JS that runs on the client. dagger.js is contrasting itself as purely runtime, build-free — you drop in a script, no compilation needed. So it’s less about runtime location (Svelte is client-side too) and more about how you get there. Svelte → compile first, then run in browser dagger.js → no compile, just run in browser
- imiric 1y agoThis is interesting. Thanks for sharing! As someone who is disillusioned by the state of modern frontend web development, I'm always curious about novel approaches that do things differently. At first glance, I like that this is buildless and declarative. Supporting Web Components is also a nice touch. However, I don't like that it abuses HTML attributes for the "directives" feature. I appreciate that these are stackable, and it seems like a concise and flexible way to specify behavior, but at the same time, it's not valid HTML, and the framework shouldn't rely on unspecified behavior of HTML parsers to ignore them. The correct approach would be to use data attributes, which would make the API more verbose, and possibly less flexible, but it ensures future compatibility across browser engines. I'm also not a fan of attributes having any sort of logic or JavaScript code in them. That is IMO an anti-pattern popularized by JSX and frameworks of the time which we've accepted as standard, for some reason. Separation of concerns is a powerful concept that simplifies development and maintenance. HTML should define the structure and content of the page; JavaScript should define the logic. Whenever you write JS inside HTML, or viceversa, you're breaking this principle. This doesn't mean that JS and HTML can't coexist in a single file―that has been possible since the dawn of the web. But it means that each layer should be concerned about a single aspect of the application. And, yes, I'm aware that Web Components also technically break this, and, no, I don't like it. Dagger.js takes this to an extreme level and seems to allow JS expressions inside text content, which is surely too inefficient to have any practical value. FWIW I experimented with own buildless and declarative micro framework a few months ago[1], after a frustrating experience with Vue. I was curious if "primitive" data binding could be used with an intuitive API, while keeping separation of concerns as much as possible, and without abusing HTML. Turns out that it's really not that difficult. It doesn't have any of the advanced features and flexibility of modern frameworks, but that was a deliberate design decision. I don't expect anyone else to use it, but I plan to adopt it in personal projects. So far it has worked well for implementing the options UI of a small browser extension. Also, for the love of all things holy, please prompt your LLM to tone down the emojis in the docs. It's quite distracting. [1]: https://github.com/hackfixme/miu https://github.com/hackfixme/miu
- TonyPeakman 1y agoThanks for the thoughtful feedback — you raise valid concerns. The reason dagger.js allows JS expressions in attributes is mostly about lowering the barrier to entry. By keeping everything in plain HTML, you can copy-paste a snippet, view-source it, and immediately see both the structure and the behavior in one place. For small widgets, docs, or internal tools, that convenience often outweighs the drawbacks. You’re right that it’s technically not “valid HTML,” and that data-attributes would be more standards-compliant. I chose the lighter +click="count++" style because it makes the examples concise and easy to reason about — essentially HTML as a living playground. The trade-off is that it bends the rules a bit. That said, I agree separation of concerns is important. dagger.js is not trying to replace large frameworks or enforce this pattern everywhere. It’s intended as a minimal option where simplicity and quick iteration matter more than strict layering. If it proves useful but the attribute style becomes a blocker, I’m very open to exploring a data-* form or even alternate syntax. Also, thank you for sharing your own framework — it looks great. Actually I’m considering adding a pre-compiled, separation-of-concerns version of dagger.js in the future to support a wider range of development needs. And thanks as well for the docs suggestion about emojis. Feedback like this really helps shape the project in a healthier direction.
- kasuu 1y agoWhat is the risk here? Are you worried that in a year it will be missing a feature you want? It's client side javascript, aside from DOM based XSS (which if reported, you can probably fix yourself), there isn't much to worry about from the security perspective. The web doesn't normally deprecate things so it's probably going to work in a year too. This is a tiny project which already requires that you know JavaScript, so you can't even claim that you can't maintain it because you don't know the implementation language. It doesn't depend on some build step (which often is the thing that breaks after a year).
- vlad1719 1y ago[dead]
- TonyPeakman 1y agoFor anyone curious, I’ve put together a collection of comparison demos here: https://codepen.io/dagger8224/pens https://codepen.io/dagger8224/pens . They show the same functionality implemented with dagger.js alongside other frameworks (credit to the original authors of those examples ). If there’s a particular feature, page, or component you’d like to see built with dagger.js, feel free to leave a comment — I’d be happy to explore and discuss it together. Thanks!