I've created yet another JavaScript framework
Tags: javascript, lit, webcomponents, webdev
Published: 2024-04-13 13:57:46

**It's 2024 and you've created yet another JavaScript framework. Seriously man!**

When talking about another Javascript framework, you may laugh and think that there are tons of proven options out there why bother creating another one? 🤷‍♂️

Let me share with you my personal story which leads to the development of a new Javascript framework. But if you don't care about my pathetic story, here is the TLDR:

> **TiniJS** is a meta framework powered by the **Web Components** technology based on the Google [Lit](https://lit.dev/) library.

> You can start by trying out [an example on Stackblitz](https://stackblitz.com/edit/try-tinijs?file=app%2Fapp.ts). Or downloading a [starter template](https://github.com/tinijs/bare-starter). Or initialize an app using the CLI, run `npx @tinijs/cli@latest new my-app` and follow the instruction.

> For more detail, please see the **Get started** section below or visit <https://tinijs.dev/>.

## The story

![Too many Javascript frameworks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kwi99az05w9syfgn7833.jpeg)

Joke aside, I'm not an expert in Javascript, but for a little bit about my background so you may know my anoyance story regarding front-end web development. I used to be an Angular developer back in the version 1 of it and currently working mainly with Vue and accasionally jQuery. I had these **3 PITA** (Pain In The \*beep\*) experience which motivated me to experiment with the TiniJS framework.

> **PITA #1 - BUILDING A GOOD UI/UX IS HARD, IT IS TEDIOUS AND TIME CONSUMING!**

Back in around 2010, there are two distint kinds of websites: the one with a ton of texts, links, barely any images here and there; and the others are with overwhelmed graphical elements such as GIF images, Flash background, rainbown cursors, ...

People tend to have the stereo type that **back-end is hard** and **front-end is easy**. It's kinda true, but not entirely, I mean, who am I to blame, right? Because with a little bit knowledge of HTML and CSS, you can pretty much build a static website very easily. But, in order to build a good UI/UX, there is much more to be considered. You have to be a master of many more things, and they are not easy at all!

![Front-end development is not easy!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77sp9asranurm9xcldl5.png)

> **PITA #2 - CSS FRAMEWORKS ARE LACK OF FUNCTIONALITIES AND CUSTOMIZING THEM IS NOT VERY EFFICIENT!**

People realized the difficulty of front-end development and started to build CSS frameworks to help with the problem. Bootstrap is one of the pioneers of this trend, other popular ones are: Foundation, Semantic UI, Bulma, Skeleton, Pure CSS, ... Those CSS frameworks are great, no doubt about that, they help us to build a good UI/UX faster, but they also have their own limitations.

First, despite the fact that all the frameworks provide certain ways to customize the style, but overall, I feel that it is not very easy and reusable to me.

![Customize CSS framework is not very efficient](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2lhj75s0sy977e8d5e48.jpg)

Second, is the lack of functionalities. I mean, they are mainly CSS, they provide some functions, usually as plugins to JQuery. Most of the cases you have to write your own Javascript to make a feature works.

> **PITA #3 - JAVASCRIPT FRAMEWORKS ARE OVERWHELMING AND SOMEWHAT REDUNDANT!**

Enter the modern era of web development, Javascript frameworks are the new trend. But the problem is that we have so many choices, it is both a blessing and a curse. They provide great functions but not very interoperable, you can't just take a piece of code from one framework and use it in another. Especially, creating a UI system with separated packages for specific frameworks is a very daunting task.

![Front-end web dev is fragmented](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cx44vzf0guksn2horak.png)

Every time I start a project or do some kind of front-end work, the fragmentation of front-end web is somewhat painful to me. That seems to be the way of life, there is no avoid, isn't it? Please don't get me wrong, I'm not against any framework, I tend to choose solutions and not technologies, so if it works for you, just go with it. But I wonder to myself is there any way to somehow unify or lessen the gap in front-end development experience? 🤔

## Introducing TiniJS

That is the reason why I experiment with the **TiniJS framework** for a while. It is a collection of tools for developing web/desktop/mobile apps using the native **Web Component** technology, based on the [Lit](https://lit.dev/) library. Thank you the [Lit](https://lit.dev/) team for creating a great tool assists us working with standard Web Component easier.

It is aimed to be as much **standard, small and versatile** as possible. Not really comparable to other frameworks and meta-frameworks, but overall, it has similar capabilities and also in the other hand, key differences. It is both a replacement choice and a complement to other frameworks. You may use TiniJS to build a various type of apps: **landing pages, SPAs, PWAs, desktop apps, mobile apps,** ... Feature-wise, anything works in Javascript should work fine in a TiniJS app.

The whole system consists of several parts, this is a quick introduction.

> Please note that **not all the parts available now**, the project is at an early stage, some are **previously experiments**, I try my best to bring them live as soon as possible. But I have limited time and resource, so please bear with me and perhaps please lend me a hand if possible. 🙇‍♂️
> The plan for V1 and its roadmap can be found at <https://github.com/tinijs/tinijs>
> **[Update - 2024/05/01]** Version 0.18.x adds [**PWA** module](https://tinijs.dev/module/pwa), [**Content** module](https://tinijs.dev/module/content) and [**Server** module](https://tinijs.dev/module/server) and many improvements.

### Core

At the core, **TiniJS** provides a conventional project structure with a streamline development pipeline. There are **folders for organizing stuffs**, a **local server for development**, upon distribution, you can choose Vite or Parcel or Webpack to **build the production**.

The core also includes: the [**Router**](https://tinijs.dev/framework/router) for navigating between pages, a simple [**Store**](https://tinijs.dev/framework/state) for global state management, [**PWA**](https://tinijs.dev/module/pwa) supported, ...

You can try example projects:
- [An example Photo Gallery App](https://stackblitz.com/edit/try-tinijs?file=app%2Fapp.ts)
- [An example To Do App](https://stackblitz.com/edit/try-tinijs-todo-app?file=app%2Fapp.ts)

### UI system

TiniJS has an **UI library where I aim to provide every commonly used components and blocks and even whole pages**. Components are architected in a special way where they are custom elements to be used not only with TiniJS, but also with other frameworks or no framework.

![Tini UI concept](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rshg9gol388nf0gsw1jt.png)

Working with reusable components is easy, usually in the form of passing props to the custom element tag. Customization can be done via props or CSS `::part()` or custom theme family or completely clone a component source, ...

Components are also able to accommodate almost any design systems with as little effort as possible. This is achieved via a theming system; the concept is this:
- Components are written **only once**, they are **headless** (without specific styles)
- Themes are organized into **Families** (aka. design systems), families define their own base characteristics, for example: Bootstrap, Material, Fluent, Spectrum, ...
- Upon the base characteristics, a family have style variants, called **Skins**, for example, the Bootstrap family may have: Light skin, Dark skin, ...

With the theming concept in mind, any app can have these theming capabilities:
- **One** theme family - could be 80% to 90% of all the web apps exist today have only 1 certain style equivalent to TiniJS 1 theme family.
- **One** theme family + multiple skins - the common use case of this is Light/Dark modes equivalent to TiniJS 1 theme family with multiple skins from the same family.
- **Multiple** theme families - highly personalized apps may have multiple theme families with one or multiple skins from each family, a certain theme will be applied depends on user reference.

For details please visit [Tini UI](https://tinijs.dev/ui).

### Web, PWA, hybrid Desktop/Mobile

A default TiniJS app is [a **single page application**](https://tinijs.dev/framework/distribution-web), it's small and fast, it can be deployed straight away as a web app. But you can also turn an TiniJS to one or all of these kinds of apps:
- [**Progressive Web App**](https://tinijs.dev/module/pwa) (PWA) - achieve with a single CLI command
- [Hybrid **Desktop/Mobile**](https://tinijs.dev/framework/distribution-mobile) apps - using Tauri 2.0 or similar tools (todo: write instruction)

### Static and Server

A TiniJS app can be started as a static web no matter big or small without a need of a server or database. You can always use SaaS services for almost any backend needs. I am also developing the [Tini Content module](https://tinijs.dev/module/content) - a file-based content management system for managing many types of content easily. Static site generation (SSG) or prerendering is also in the plan.

An [optional Nitro server](https://tinijs.dev/module/server) for **server/API routes** and other **server stuffs** if you need to handle backend tasks and refer to serve the web app from a Node server instead of a static host. I am limit in development capacity, so server side rendering (SSR) may not be supported in the first version, instead I plan for semi-SSR, where servers will serve single page to users and serve a minimum server-side rendered content to bots.

### Features and modules

Feature-wise, since a TiniJS app is **based on standard web technology**, therefor [any libraries and features those work in browser](https://tinijs.dev/toolbox) will probably work in a TiniJS app. So, you may **not worry about features** compared to other frameworks. You can even use other frameworks inside a TiniJS app, for example init and mount a Vue app to an element inside a TiniJS page.

There is also [a modular architect](https://tinijs.dev/module) so that certain modules can tap into the workflow of a TiniJS app, create a more streamline development pipeline.

### Tools

The official CLI tool provides some convenience commands for working with a TiniJS app.
- `new` - create new projects with ready-to-use templates
- `dev` - start local development server
- `build` - build production distribution
- `preview` - preview the production build before deploying
- `generate` - generate components, pages, utils, ...
- `module` - manage Tini Modules

Besides, the CLI is **generic enough to be used outside of a TiniJS app, in any project of any kind**. It has [an expandable architect](https://tinijs.dev/cli/expansion) where you can expand more commands to be used in other automation tasks. Some of the official expansions such as `ui` command (from Tini UI) to handle UI tasks or `content` command (from Tini Content) to handle content related tasks, ... You can create [a CLI expansion pack for your own purpose privately or sharable](https://tinijs.dev/cli/expansion#author-an-expansion).

OK, enough talking, show me some actions! 👌

## Get started

**Tini** (or "[Tí nị](https://translate.google.com/?sl=vi&tl=en&text=t%C3%AD%20n%E1%BB%8B&op=translate)" in Vietnamese - meaning something very small in an adorable way).

To quickly create a **TiniJS** project, you can use the [CLI](https://tinijs.dev/cli) to initialize a template.

```bash
npx @tinijs/cli@latest new my-app
```

The above command creates an app by downloading the **Bare** template. In the future, I would like to provide several starter templates. You can also create your own templates and share them with the community or for your own private use. Currently, these templates available:

- [Bare](https://github.com/tinijs/bare-starter) (default) - minimum structure of a TiniJS app.
- [Blank](https://github.com/tinijs/blank-starter) (flag `-t blank`) - includes router, state management, meta tags management and the [Bootstrap theme family](https://tinijs.dev/ui).

Now, inside the project you can run `npm run dev` to start the development server. You may start development by edit the file `./app/app.ts` which is the root component of the app. For how to work with custom elements using Lit please visit [Lit component](https://lit.dev/docs/components/overview/), there are some differents between `LitElement` and `TiniComponent`, but for now you can modify `static styles` and `render()` as you would normally do.

To build the distribution, run `npm run build` and optionally run `npm run preview` to preview the production build. You can now deploy the `.output` folder to any static host.

You may want to check these examples to see more detail how a TiniJS app works.

- Gallery App - [https://stackblitz.com/edit/try-tinijs](https://stackblitz.com/edit/try-tinijs?file=app%2Fapp.ts)
- To Do App - [https://stackblitz.com/edit/try-tinijs-todo-app](https://stackblitz.com/edit/try-tinijs-todo-app?file=app%2Fapp.ts)
- Homepage - <https://github.com/tinijs/tinijs/tree/main/apps/tinijs.dev>

That is a basic introduction to the **TiniJS framework**, for more please visit: <https://tinijs.dev>.

---

Next topic: [**The structure of a TiniJS app and work with Components**](https://dev.to/lamnhan/getting-started-with-tinijs-framework-881)

Thank you for spending time with me. If there was anything not working for you, please leave a comment or [open an issue](https://github.com/tinijs/tinijs/issues/new) or ask for help on [Discord](https://discord.gg/EABbZVbPAb), I'm happy to assist.

**Wish you all the best and happy coding!** 💖