copied to clipboard

Preamble

A Quick Forewarning

Elegance is still in very early development.
There are absolutely no guarantees of backwards compatibility, security or really anything.
As such, elegance isn't really meant for production, yet.

What is Elegance?

Elegance is an opinionated, strict, compiled, fully-typescript,
web-framework designed for building feature-rich, yet fast and efficient web pages.

Elegance is written fully by hand, and dependencies are used very sparsely.
As of writing, esbuild is the only dependency.

A simple, fully-working (non gzipped) elegance page transfers only 4kB of data!For context, an "empty" (gzipped) react app on average transfers roughly 200-300kB of data.

This lack of JS sent to the browser is achieved through not creating unnecessary, wildly complex rude goldberg machines; and compilation instead of interpretation.

How Elegance Works

File Structure

An Elegance.JS projects file structure is akin to that of something like a Next.JS project.
We use filesystem routing, where each directory contains a page.ts, and an info.ts file.

Page Files

The page.ts file has one requirement, it must export a page object, which is of type EleganceElement<"body">

export const page = body ({
    style: "background-color: #000; color: #fff;",
},
    h1 ("Greetings Traveler!"),
);

Elements are created using simple, ambient global functions.
The above body() call, for example, gets turned into this.

{
    tag: "body",
    options: {
        style: "background-color: #000; color: #fff;",
    },
    children: [
        {
            tag: "h1",
            options: {
                innerText: "Greetings Traveler!",
            },
            children: [],
        },
    ],
}

The estute among you may have noticed that the result can easily be serialized into HTML or JSON.
This is precisely what the Elegance compiler does.

It recursively goes through the page, notes down any points of interest (more on this later),
and then serializes each element.

The resulting data can then either be used to serve static HTML pages,
(which still have all the normal features of Elegance, but won't get re-rendered),
or dynamically server-rendered content.

Info Files

The info.ts file also has only one requirement, it must export a metadata function, which then resolves into an EleganceElement<"head">

export const metadata = () => head (
    title ("The BEST Page Ever!"),
);

Metadata is of course a function, so that you may dynamically generate page information.

This is useful for something like a social media page,
where you may want need to fetch information about a post, and then display it in a nice rich embed.

Compilation

Elegance exposes a function called compile() which your project should call to build itself.
Compilation handles generating page_data files, HTML, JSON, transpilation of ts into js, etc.

We will explore compilation, state, reactivity, optimization, static generation, hot-reloading, and many of the other features of Elegance in greater-depth later on. However, this is all that you need to know for now.

Installation

GitHub

As Elegance is still in it's formative stages, we haven't yet published to things like the NPM registry.
However, installation is still quite simple.

First, decide where you'll want Elegance to live.
On a linux-based system, somewhere like ~/bin/elegance is a good place.
Just remember where it is! You'll need it later.

Install git for your system, if you haven't already.

Next, open a terminal / command prompt window, and issue the following the command.

git clone https://github.com/valdemar-dev/elegance-js [your destination folder]

You have now installed Elegance.JS onto your system. Congratulations!

Your First Page

Making a Project

Now that Elegance is installed on your machine, it's time to make your first page.
With your terminal still open, go ahead and make a new a directory where your project will live.

Once that's done, navigate to the directory you just made, and run this command.

npm init -y && npm install esbuild

This will initialize npm, and install esbuild, Elegances only dependency.

For the unitiated, esbuild is a ridiculously fast JS bundler written in Go.

Next, you'll need to link Elegance to your project.

npm link [where you installed elegance]
(you might need sudo for this if you're on linux)

Typescript Configuration

Now, for the TypeScript users, you'll want to do these next few steps.
First, boostrap a tsconfig.json so typescript works properly.
Note: You might need to set your moduleResolution as bundler, or this might not work.

Create a file at the root of your project called env.d.ts
And put this inside of it.

/// <reference path="elegance-js/types/global" />

This takes the ambient global types from Elegance, and puts them into your project.
If all goes well, Elegance should be setup fully now!

Creating Pages

Like we mentioned earlier, a page requires two files. info.ts & page.ts
So, let's create those, shall we?

At the root of your project, create a directory. You can call it pages, app, whatever you want.

In this new directory, create a page.ts file.
Just for a start, put something simple into it. Like this.
We'll get whacky and crazy later on, don't worry.

export const page = body ("Greetings Traveller!");

Next, create an info.ts file, and again, put something simple into it.

export const metadata = () => head (
    title ("The BEST Page Ever!"),
);

Building your Project

Create an index.ts file at the root of your project.

Elegance exposes the compile() function from it's build process,
which we'll be using to compile your project.

import { compile } from "elegance-js/build";

compile({
    environment: "development",
    outputDirectory: "./.elegance",
    pagesDirectory: "./pages",
    writeToHTML: false,
});

Here's an example usage of the compile() function.

environment: "development"
Means that Elegance won't minify your page code, and will create a 'watch-server',
which will auto-reload your pages when you save them.

outputDirectory: "./.elegance"
This is where Elegance will put it's compiled files into.,
We wouldn't recommend changing this, however, you can, if need be.

pagesDirectory: "./pages"
This is the directory where you put your pages.
You should make it match whatever you named the directory obviously.

writeToHTML: true
This makes Elegance write static HTML files, instead of keeping the generated page JSON
You can turn this off if you want to server render per-request.

Running your Project

You can choose how to run your own project.
Elegance should work with most JS runtimes like Node, Deno, etc.
However some (like Deno), may require a little tweaking.

More about running here.

For the purposes of this tutorial, we'll try to keep it simple.
Simply issue the following command in your terminal.

npx tsx index.ts && cd .elegance && python3 -m http.server 3000

This'll take your index.ts run it, and then serve the
generated files over a simple Python HTTP server.

And that's it! You can view your shiny new webpage at the URL, localhost:3000.