Skip to content

Write vanilla javascript using JSX syntax without virtual DOM or Proxy magic

License

Notifications You must be signed in to change notification settings

ayushmanchhabra/vsx

Repository files navigation

vsx

Write vanilla JavaScript in JSX.

Getting Started

  1. Install via your preferred node modules manager or CDN.
  2. With TypeScript, add these options in your tsconfig
    "jsx":"react",
    "jsxFactory": "VSX.createElement",
    "jsxFragmentFactory": "VSX.createFragment",

Design

If you think of DOM as computer memory, then an element is a variable. To update a variable (element), you access it via a pointer (id property). This is called state. State refers to an element with a unique id. Elements without id are regular XML markup.

const [count, setCount] = createState(0);

Since there is no virtual DOM or proxy magic, number needs to be inserted in the markup so that a unique id can be generated which is referenced by setCount function.

<>
  <button onClick={setCount(count().value - 1)}>-</button>
  <div>{count}</div>
  <button onClick={setCount(count().value + 1)}>+</button>
</>

A component is a way to write markup such that it abstracts away the document.createElement function calls.

An effect tracks changes to certain elements via the MutationObserver API. Effects should be used to make calls to external systems such as window.localStorage or network requests.

Here's the complete example of a counter:

import VSX, { createEffect, createState } from "vsx";

const Counter = () => {
    const [count, setCount] = createState(0);

    createEffect(() => {
        localStorage.setItem("count", count);
    }, [count]);

    return (
        <>
            <button
                onClick={() => setCount(count().value - 1 )}
            >
                -
            </button>
            <span>
                {count}
            </span>
            <button
                onClick={() => setCount(count().value + 1 )}
            >
                +
            </button>
        </>
    )
}

Contributing

  • Conventional commits are enforced.
  • Pull requests are squashed and merged onto main branch.
  • Lint your code before commiting your change.
  • Add tests whenever possible.

Inspiration/References

Contributing

To open a bug report or to add a feature request, open a PR and edit Roadmap in README.md. Once that bug is resolved/feature is implemented, it will be moved to the CHANGELOG.md.

Roadmap

  • Abstract out boilerplate not complexity. If the complexity is changed, people have to change their mental model of how it works.
  • Provide better developer experience such as throw errors when common mistakes have been made. For example: throw error when props have been added to a fragment (since the fragment is removed after transpiling.
  • Maybe throw an error or display warnings if components are missing certain accessibility features/standards.
  • No virtual DOM so its performance depends on the browser's performance.

Bugs

Features

  • createElement
  • createFragment
  • createState
  • createEffect
  • createRouter
  • Use Proxy for State object to allow React like state changes
  • Pass special children prop into components
  • Add support for arrays

Chores

  • Add end to end testing
  • Explore tagged templates
  • Move releases information to CHANGELOG.md
  • Might have to add custom tsconfigs for different bundlers

License

MIT