Sprocket

A library for building live views and real-time server components in Gleam ✨

Package Version Hex Docs

Demo Documentation

Heavily inspired by Phoenix LiveView, React and Elm. The name “sprocket” is loosely derived from the metaphor of a bicycle’s sprocket, cassette and chain.

Sprocket combines the best of LiveView server-side productivity and scalability, React components and Elm functional state management patterns implemented in Gleam, a type-safe language built on the venerable BEAM (Erlang Virtual Machine).

An initial static view is rendered as HTML on the “first paint” which then establishes a connection to the server over a WebSocket to facilitate sending browser events and receiving view update diffs. These updates are patched into a client-side in-memory representation of the DOM and rendered to the browser using morphdom. Declarative views are built using functional components that accept props and re-render each time those props change and reducers are used for state management using strongly-typed models and message structs.

Under the hood, a reducer is a lightweight Gleam Actor OTP process (i.e. gen_server) and changes to the state (via dispatch) result in a re-render of the view.

Component interfaces snap together and are used to create higher-level views. Data flow is “uni-directional” in that State always flows down into components as props while Events flow up out of components through event handlers (which are also passed in as props, e.g. on_some_event("Something happened")).

This library is currently in a proof of concept state and should be considered highly unstable. There is still a lot of work to be done, including adding support for more event types, introducing additional hooks, improving unit test coverage, providing extensive documentation of modules and API, and optimizing performance.

Key Features

Example

Clock Component

type Model {
 Model(time: Int, timezone: String)
}

type Msg {
 NoOp
 UpdateTime(Int)
}

fn update(model: Model, msg: Msg) -> Model {
 case msg {
   NoOp -> model
   UpdateTime(time) -> {
     Model(..model, time: time)
   }
 }
}

fn initial() -> Model {
 Model(time: erlang.system_time(erlang.Second), timezone: "UTC")
}

pub type ClockProps {
 ClockProps(label: Option(String))
}

pub fn clock(ctx: Context, props) {
 let ClockProps(label) = props

 // Define a reducer to handle events and update the state
 use ctx, Model(time: time, ..), dispatch <- reducer(
   ctx,
   initial(),
   update,
 )

 // Example effect that runs whenever the `time` variable changes and has a cleanup function
 use ctx <- effect(
   ctx,
   fn() {
     let cancel =
       interval(
         1000,
         fn() { dispatch(UpdateTime(erlang.system_time(erlang.Second))) },
       )

     Some(fn() { cancel() })
   },
   WithDeps([dep(time)]),
 )

 let current_time = int.to_string(time)

 render(
   ctx,
   case label {
     Some(label) -> [span([], [text(label)]), span([], [text(current_time)])]
     None -> [text(current_time)]
   },
 )
}

Parent view

pub type ExampleViewProps {
 ExampleViewProps
}

pub fn example_view(ctx: Context, _props: ExampleViewProps) {
 render(
   ctx,
   [
     html(
       [lang("en")],
       [
         head([], [link([rel("stylesheet"), href("/app.css")])]),
         body(
           [class("bg-white dark:bg-gray-900 dark:text-white p-4")],
           [
             component(
               clock,
               ClockProps(label: Some("The current time is: ")),
             ),
           ],
         ),
       ],
     ),
   ],
 )
}

Getting Started

To get started with Sprocket, follow the instructions below:

  1. Clone the Sprocket starter repository:
git clone https://github.com/bitbldr/sprocket_starter.git
  1. Install the required dependencies:
gleam deps download
yarn
  1. Start the development server:
yarn run watch
  1. Open your web browser and visit http://localhost:3000 to see the starter app.

Installation

This package can be added to your Gleam project:

gleam add sprocket

For getting started with Sprocket, refer to the Official Docs. Here you will find detailed examples and tutorials. These docs are build with sprocket, which also make them an excellent reference implementation github.com/bitbldr/sprocket_docs.

API Documentation

API documentation can be found at https://hexdocs.pm/sprocket.

Roadmap

Sprocket is still in its early stages and has a roadmap for future development. Here are some of the planned improvements:

Contributing

Contributions to Sprocket are welcome and encouraged! If you would like to contribute, please follow the guidelines outlined in the CONTRIBUTING.md file.

License

Sprocket is released under the MIT License.

Search Document