Arctic

Package Version Hex Docs

Arctic is a declarative web framework for building fast sites in the way you want. You specify what sorts of elements a markup file can have and how you notate those elements, and Arctic cranks out an optimized site that can be hosted on a static CDN and supported by servers or serverless functions. This maximizes page startup times.

Arctic doesn’t take away your range of expression, it merely tries to act as shorthand. To do so, Arctic uses a modular process that lets you describe each part of each page in the way you want. A page can be mostly written in customized markup, and then in the middle you can write latex, HTML, gleam, or your own thing!

Arctic is still very much a work in progress. Packages for common languages like those mentioned above should be added. We need better comments and documentation. Pages aren’t well optimized yet. The rendering part is still pretty DIY. If you’re interested in this project, please chip in! Anyone is welcome to contribute. Also consider sponsoring me, so I have more time to work on this!

Arctic is very frontend-oriented. I think it would be paired very well with the sort of work coming out of the Pevensie project, which is generally on the server side. In the more immediate future, Wisp/Mist is a great Gleam backend that’s available right now! More generally, you should be able to pair an Arctic codebase with servers written in any language, or serverless functions, or just serve the Arctic site statically from a CDN!

gleam add arctic
import arctic/build
import arctic/collection
import arctic/config
import arctic/parse
import app
import lustre/element/html
import snag

pub fn main() {
  let post_parser = parse.new()
    |> parse.add_inline_rule("_", "_", parse.wrap(html.i))
  let posts = collection.new("posts")
    |> collection.with_parser(post_parser)
    |> collection.with_index(app.post_index)
    |> collection.with_renderer(app.post_renderer)
  let config = config.new()
    |> config.home_renderer(app.render_homepage)
    |> config.add_collection(posts)
    |> config.add_main_page("404", app.unknown_page_html)
  let res = build.build(config)
  case res {
    Ok(Nil) -> io.println("Success!")
    Error(err) -> io.println(snag.pretty_print(err))
  }
}

Further documentation can be found at https://hexdocs.pm/arctic.

Development

Some features mentioned here can be separate libraries on Hex, called arctic_rss or whatever and allowing imports like arctic/rss. That’d be cool. Maybe arctic_plugin_ is a better prefix, with arctic/plugin/rss for example, to ensure safer namespacing. Obviously anyone could develop these packages, and a bigger ecosystem is better!

Here’s a list of things I want to accomplish. They generally aren’t hard. For some of the components I imagined just shellouting to other tools and simplifileing the result back into memory, or into an assets folder, or whatever. I already do this with latex on my personal site. However, the list is long, and contributions from others would help a lot in getting it done. Note that there are other important things Arctic needs to be able to do; me not including them here just means that Arctic is already doing them :)

Something that is a pain point for me is scale: handing around the entirety of all pages in all collections, in memory via pointer-chasing, could never scale to the number of pages of a large corporation. That limits one’s growth when using Arctic. I think a streaming version (as well as one that doesn’t need the posts to be sitting in a directory on each developer’s machine!) can be implemented, but the API would need to change a bit to enable that. Servers searching through pages should also not have to re-process the markup files; we could build a database during processing. Ideally much of this should be as incremental as possible, which can be done well with caching. There’s much figuring out to do.

Search Document