npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@wrnrlr/prelude

v0.1.6

Published

A signal based frontend library with fine-grained reactivity

Downloads

334

Readme

Prelude

Home NPM JSR

Prelude lets you develop web applications in a familiar component-based functional style. It is build with the desire to have a lightweight frontend framework that works using just JavaScript but that nontheless can handle complex web applications without sacrificing on developer expierence.

Get Started

Prelude works with most popular JavaScript runtimes: Node, Deno, Bun or the borwser. It is available on NPM and JSR under the package named @wrnrlr/prelude.

The quickest way to get started with Prelude is uing the Playground app on the homepage. It offers a IDE complete with a code editor, live preview and a number of examples. Aternativaly you can develop on your local machine using vite.

Some Prelude APIs can also be used in the REPL to expore their behaviour interactively.

Basic Example

This is a example of a button that increments a counter when it is clicked.

<!DOCTYPE html>
<title>Counter</title>

<script type="module">
  import {h, signal, render} from 'https://esm.sh/@wrnrlr/prelude'

  function Counter() {
    const n = signal(1)
    return h('button', {onClick: e => n(n=>n+1)}, n)
  }

  render(Counter, document.body)
</script>

Hyperscript

Prelude does not use JSX or a templating language to descript html instead we use a DSL called HyperScript.

The h function is used in either of two ways based on the type of the first argument, when it is a string it will create a html element like , and when it is a function it will create a reactive component.

h('div',{},[
  h('label','Name'),h('input',{})
])

Event Handler

Prelude tries to integrate with the existing web APIs as much as possible, handeling user events is no different, use a function to the event callback.

In the following example we listen for onclick events for a button, and increment the value of the n signal.

h('button', {onClick:e => n(i => i + 1)}, n)

Be adviced, the event handler MUST always have one argument even if this is not being used, lest HyperScript confuses it for a signal and ignores the events.

// Ok
h('button', {onClick: e => console.log('Ok')})
h('button', {onClick: _ => console.log('Ok')})
// This event handler will be ignored
h('button', {onClick: () => console.log('Wrong')})

Reactivity

Signals

A signal is an object that holds a value with a setter to update this value and a getter that returns this value whenever it is updated.

Create signal.

// Create a signal with value one
const n = signal(1)

// Get value from signal
n()

// Set value for signal
n(2)

// Set value with an update function
n(i=>i+1)

// Derived signal
const n2 = () => n() * 2

Effects

The effect function lets you subscribe to signals and perform side-effects whenever the signal chages.

const a = signal(1), b = signal(2)
effect(() => console.log('a+b', a()+b()))
const c = () => a()+b()
effect(() => console.log('c', c()))
a(i => i+1)

Memo

The memo function caches the result of the function passed to it.

const n2 = memo(() => n() * 2)

Untrack

Conditional Rendering

h(Show, {when:() => n()%2 === 0, fallback:'odd'}, 'even')

It is also possible to conditionally render a component by prefixing it with a JavaScript and-expression, like in the example below, but using Show is going to be faster.

h('',show&&'Hi')

Rendering Lists

h(List, {each:['a','b','c']}, (v,i)=>`${i()}:${v()}`)

Fetching Resources

The resource() function lets you define a asynchronous signal.

resource(async ()=>getPosts())

Dependency Injection

Prelude supports dependency injection with the contect and useContext APIs.

const CounterCtx = context()
const useCounter = () => useContext(CounterCtx)

function CounterProvider(props) {
  const count = signal(0)
  const increment = () => count(i=>i+1)
  return h(CounterCtx.Provider, {value:[count,increment]}, props.children)
}

function Counter() {
  const [n, increment] = useCounter()
  return h('button', {onClick:e=>increment()}, n)
}

function

function App() {
  h(CounterProvider, h(Counter))
}

Router

h(Router,[
  {path:'/', component:Posts},
  {path:'/user', component:Users}
])

Learn More

  • API Reference
  • SolidJS Docs: The documentation of SolidJS also a good place for background information because Prelude is lacking extensive documentation at this time. Prelude started as a SolidJS clone, but with better HyperScript support. A lot of the concepts are the same but naming conventions can vary.

TODO

  • [ ] tailwind styling
  • SSR
  • Hydration
  • Components
    • [ ] Select
    • [ ] Multiselect
    • [ ] DataTable
    • [ ] Dropdown
    • [ ] Dialog
    • [ ] Dynamic

Links