top | item 40340901

Show HN: Boxwood – simple templating engine for JavaScript, in JavaScript

59 points| emilos | 1 year ago |github.com

Hey!

A while back, I wrote a templating engine (MIT License), which I mostly use for small side projects, either static or ssr generated. Simplicity is one of the main goals.

I'll be happy to answer any questions. The main goal for sharing it is to simply get some feedback.

Best, Emil

26 comments

order

ricardobeat|1 year ago

Curious about the motivation for this. It’s basically where we were at right before JSX took over, e.g. mercury [1] and the old hyperscript.

Except it’s missing the ability to hydrate components on the client and re-render.

[1] https://github.com/Raynos/mercury

simonbarker87|1 year ago

Not the OP but I’m going to guess that, like me, they prefer to render server side where possible, don’t like Handlebars or Pug etc and don’t want to get lost in the quagmire than it NextJS.

I use htmx for as much of my network requests and UI updating as possible as it’s faster to implement features, faster the render and easier to reason around than a SPA front end and JSON response backend - there’s a chance the OP is in a similar boat.

The downside to a JS SSR driven app is the backend templating situation isn’t as expressive as JSX and can feel a bit limiting.

Hopefully OP will chime in and correct of confirm my assumptions.

madeofpalk|1 year ago

It's funny because this syntax is basically non-JSX JSX/React anyway. I'm sure you could write a JSX transform for this.

afavour|1 year ago

As per the op: “simplicity is one of the goals”

Not every webapp needs client side hydration. It’s very often wasted CPU cycles on a page that’ll be unloaded three seconds later. Personally I’m happy to see projects like this that live outside the monoculture.

javajosh|1 year ago

I don't really need a library like this, but I want to comment to say how much I like the way you made it. Very minimal in itself and also in its dependencies. Very clear documentation in the readme. I wish more libraries and tools were distributed like this.

seer|1 year ago

I wonder if it has an intermediary step that concerts the template to AST?

I like my tools to have as much types generated from context as possible (types from OpenApi, from graphql or from sql queries) and was looking to build a tool like that for handlebars. Idea being that it would tell you which types the template variables used so you could avoid stupid errors at compile time.

It seamed handlebars could provide an AST, but it was kinda hard to used so I scrapped the effort.

Maybe this would be more condusive?

emilos|1 year ago

Having a type system wasn't really the goal here (there's enough great tools that handle that), but there's plenty of options that could work for you, if you're willing to build it. Some quick ideas:

1. You could add a jsdoc comment per component, let your tool read it and treat it as the source of truth 2. The template is just a js file, so you could parse it, get the params of the fn and try to deduce the types based on the usage 3. You could use typescript and export types 4. Serialize/normalize data before passing to the templating engine

zeroq|1 year ago

Reminds me of Smarty, a famous templating language written in templating language.

MatthiasPortzel|1 year ago

If I understand this correctly, it seems similar to one use-case for NanoJSX.

martinbaun|1 year ago

Sweet, I have been looking into Node for my Python SSR webapps, but Pug and Handlebars are just not cutting it. Jinja templating language is just soooo good.

This looks like what I wanted in a templating language

lf-non|1 year ago

Try edge: https://edgejs.dev/

It is mature and feature rich. I like that the expressions can be plain js and it is not coupled with html.

hombre_fatal|1 year ago

Fwiw, you can use JSX without React.

Another project on the HN homepage at the moment happens to do this: https://www.val.town/v/maxm/staticChess

    const { renderToString } = require('react-dom/server')

    renderToString(<ul>{[1, 2, 3].map(n => <li>{n}</ul>)}</div>)
Granted, you have to configure it so that JSX is allowed in your JS. For example, by running your code as `tsx server.js`, but I find it so much better than Pug/Nunjucks of yore that it makes up for that downside.

evbogue|1 year ago

Reminds me a little of https://github.com/ohanhi/hyperscript-helpers

Could this also work in the browser?

emilos|1 year ago

You could get a simple version with little modifications, but it wouldn't really be super useful unless you potentially start adding things like lifecycle events (like mount, unmount), reactivity (state, effects).

Otherwise you might end up reimplementing those.

The intentions of the tool were the server side and static use cases and I didn't plan to use it on the client side.