JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q34274F
  • License MIT

A front-end framework for building bundle-less, fine-grained web apps in browser-native JS.

Package Exports

  • grainstack

Readme

grainstack

A front-end framework for building bundle-less, fine-grained web apps in browser-native JS.

What

This is an alternative stack.

  • grainstack : react - Front-end framework providing reactive updates.
  • jsx-to-h : babel - Optional JSX support by transforming it to hyperscript.
  • web-imports : webpack - Optional support for resolving dependencies of dependencies.

Why

To reduce JavaScript fatigue.

ES modules in the browser was a major advancement in web technology that paved the way for isomorphic code sharing and a bundle-less developer experience that reduced complexity and overhead. It suddenly became possible to use packages without a compile step, resulting in a leaner project space.

Packages like htm and hyperscript allowed for a react-like developer experience in vanilla JS. So grainstack was created to provide the reactivity solution, and then it was possible to make a reactive SPA using only built-in language features.

However, vanilla JS is missing some features which are arguably worth installing such as typing, JSX, and the ability to access a thriving package ecosystem.

Additional features can be added by introducing a build step, and if babel is no longer needed for JSX transformation, then it can be removed from the project in some cases.

Some common build steps are:

  1. Support type annotations.
  2. Support JSX.
  3. Support importing from node_modules and dependencies of dependencies.

Covering these common use cases means that many projects might not need plugin systems such as babel or webpack anymore.

Overview

grainstack is a collection of:

  • reactivity.mjs - Reactive state management which replaces mobx.
  • history.mjs - Reactive history.
  • routing.mjs - Reactive routing.
  • grainstack-hyperscript.mjs - A custom implementation of hyperscript with support for es modules, and it supports these props: onmount, unmount, disabled, checked, class.
  • html-tag.mjs - If you are not using JSX, you can use this html template tag literal which was made by combining the custom hyperscript with standard htm.

Importing

The most functions are exported from a single place:

import {
  reactive,
  history,
  registerRoute,
  html,
  h,
} from 'grainstack'

There are sub-packages which have additional exports. They can be imported using a subpath or a direct path to the file in the esm or cjs folder.

// subpath imports:
import * as reactivity from 'grainstack/reactivity'
import * as history from 'grainstack/history'
import * as routing from 'grainstack/routing'
import * as hyperscript from "grainstack/hyperscript"
import * as htmlTag from 'grainstack/html-tag'

// direct imports:
import * as reactivity from 'grainstack/esm/reactivity.js'
import * as reactivity from 'grainstack/cjs/reactivity.js'

JSX

If you would like to use JSX instead of html template tag literals, you can do so using the jsx-to-h package. Then, h must be present in any file which has JSX. This is similar to how React has to be present in any file which has JSX.

// These imports are analogous to each other with respect to JSX being present in the file.  
import {React} from 'react'
import {h} from 'grainstack'

// `jsx-to-h` will transforms this into: const element = h('div')
const element = <div/>

Serving Front-End JS

Serving files which have been transformed by web-imports is highly recommended. Similar to how jsx-to-h provides an improved developer experience (DX) by introducing JSX, web-imports improves DX by allowing the browser to import from node_modules by transforming the code. It can be used in both SSG and SSR contexts. See the web-imports documentation for more information.

Read More

External References

Here are some packages which go well with this one.

  • goober - A CSS solution is needed and import {css} from 'goober' is a simple way to get co-located CSS-in-JS.