+++
title = "Building view-trees: Intro [Part 1]"
date = 2023-12-01
+++
When I was at Etsy, we built a server-side component library called
View Trees, but also called `neu` (because this was quicker to type).
This is referenced in this [Code As Craft][cac] blog post, which is about
extending/updating the framework to output server-rendered JSX components.
After futzing around with [Vue][vue] in present-me, and then reading more about
similar-to-neu approaches for doing client-side interaction (like [htmx][htmx],
and others) based on server side rendering I wanted to revisit this library,
but from a Go perspective.
---
This is going to be a series of posts describing an iterative approach to
building this out, aming to explain why things look and the way they do through
specific problems and solutions to them.
**Things to keep in mind**
- In Go, we have built-in templates with the [`html/template`][1]
package, and a standard way of compiling and rendering templates.
We're not introducing a new templating language. And want to leverage
the way folks already write their templates, but give them different
ways to compose them (not inclusion, not inheritence).
- There are standard HTTP handlers in the `net/http` package, try
to integrate with that using middleware (and other standard patterns)
and not introduce any http routing or anything else.
- We want to make the interfaces small, and the composition simple and obvious.
- Errors are recoverable!
## How does go do templates?
The idiomatic way to render HTML templates is to write some data
to a buffer via `tpl.Execute`:
```go
import "html/template"
contents := `
Hi, {{ .Name }}
`
tpl := template.Must(template.New("hi").Parse(contents))
var bs bytes.Buffer
err := tpl.Execute(&bs, map[string]string{"Name": "Stan"})
```
The above snippet is an extremely simplified version of what you would
do. Idiomatically, one would expect template compilation from external
files that are embedded into your binary and compiled and a named type
for the template data, error handling, and maybe writing to
an `http.ResponseWriter`.
# Where are we going?
```go
html, err := Render(PersonView(Person{Name: "Stan"}))
```
Conceptually, what we have is piece of data, let's say a `Person` struct,
and an html view of that that knows how to take that data and render
it into HTML. We can, of course, just make a function that does this
for the use case above.
But what we want is something like this:
- A `Render` function that render's a view.
- A view that is parameterized by a struct.
- Outputting valid HTML.
The larger semantic difference is we are lifting the way we desribe
our data inputs and views into being first-class "objects" (structs
that can possibly have behaviors and guarantees) so we can leverage
the language to do composition, parameterization, polymorphism,
etc... so we can do things like components :)
---
### Next:
- [The basics][part-2]
- [Error handling][part-3]
- [Async data fetching][part-4]
- [http.Handler][part-5]
- [Updating the base interface][part-6]
- [What's up with Renderables][part-7]
[cac]: https://www.etsy.com/codeascraft/mobius-adopting-jsx-while-prioritizing-user-experience
[1]: https://pkg.go.dev/html/template
[htmx]: https://htmx.org/
[vue]: https://vuejs.org/
[part-2]: /writes/building-view-trees-in-go-part-2
[part-3]: /writes/building-view-trees-in-go-part-3
[part-4]: /writes/building-view-trees-in-go-part-4
[part-5]: /writes/building-view-trees-in-go-part-5
[part-6]: /writes/building-view-trees-in-go-part-6
[part-7]: /writes/building-view-trees-in-go-part-7