Robin Marillia
Back to home

Fullkit, a Django-like framework in typescript

Following the experiment of creating jSimple I wanted to go further and create a fullstack framework. I wanted to create something that would be easy to use and that would be a good alternative to the current frameworks to build small website. The excuse was to rewrite my project Techwatch from SvelteKit to my own janky framework (great idea!).

Philosophy

Similar to class based view in Django, Fullkit uses classes to define views and layouts. It is not as flexible as Django because the inheritance story is not great in javascript but you can inherit from either the View class or the Layout class. You then define an HTML template that will be rendered by the server.

There are some addition to standard HTML like the include tag that allows you to include another template and the for tag that allows you to loop over an array. These are done using my compile-include-html package. Just like Django, to get the data from the View to the template you use the getContextData() method.

Get started

To install the server library enter the following command:

npm install @fullkit/server @fullkit/stem-renderer

You can also install only the packages you like for exemple @fullkit/client to use the reactivity functions inspired by Solidjs.

npm install @fullkit/client

Example

// index.ts

import { View } from "@fullkit/stem-renderer";

export class Page extends View {
  templateName = "index.html";

  getContextData() {
    return {
      title: "Hello World",
      nav: [
        { href: "/", name: "home" },
        { href: "/about", name: "about" },
      ],
    };
  }
}
<!-- index.html -->

<h1>{title}</h1>
<nav>
  <ul>
    <for condition="const item in nav">
      <include src="nav_item.html" with="item: item"></include>
    </for>
  </ul>
</nav>

Features

Fullkit uses vite-plugin-ssr under the hood.

File base routing

Note: The root page must be under an index folder.

Layouts

// layout.ts

import { Layout } from "@fullkit/stem-renderer";

export class MainLayout extends Layout {
  templateName = "layout.html";

  getContextData() {
    return {
      title: "Site title",
      nav: [
        { href: "/", name: "home" },
        { href: "/about", name: "about" },
      ],
    };
  }
}
<!-- layout.html -->

<h1>{title}</h1>
<nav>
  <ul>
    <for condition="const item in nav">
      <li><a href="{item.href}">{item.name}</a></li>
    </for>
  </ul>
</nav>
<slot></slot>
// about.ts

import { View } from "@fullkit/stem-renderer";
import { MainLayout } from "./layout.ts";

export class Page extends View {
  templateName = "index.html";
  layoutClass = MainLayout;
  getContextData() {
    return {
      content: "About page !",
    };
  }
}
<!-- index.html -->

<p>{content}</p>

The resulting html will be:

<h1>Site title</h1>
<nav>
  <ul>
    <li><a href="/">home</a></li>
    <li><a href="/about">about</a></li>
  </ul>
</nav>
<p>About page !</p>