Build apps for pixel-based displays.

Pixlet

Build & test GoDoc

Pixlet is an app runtime and UX toolkit for highly-constrained displays. We use Pixlet to develop applets for Tidbyt, which has a 64x32 RGB LED matrix display:

Example of a Tidbyt

Apps developed with Pixlet can be served in a browser, rendered as WebP or GIF animations, or pushed to a physical Tidbyt device.

Documentation

Getting started

Install on macOS

brew install tidbyt/tidbyt/pixlet

Install on Linux

Download the pixlet binary from the latest release.

Alternatively you can build from source.

Hello, World!

Pixlet applets are written in a simple, Python-like language called Starlark. Here's the venerable Hello World program:

load("render.star", "render")
def main():
    return render.Root(
        child = render.Text("Hello, World!")
    )

Render and serve it with:

curl https://raw.githubusercontent.com/tidbyt/pixlet/main/examples/hello_world.star | \
  pixlet serve /dev/stdin

You can view the result by navigating to http://localhost:8080:

How it works

Pixlet scripts are written in a simple, Python-like language called Starlark. The scripts can retrieve data over HTTP, transform it and use a collection of Widgets to describe how the data should be presented visually.

The Pixlet CLI runs these scripts and renders the result as a WebP or GIF animation. You can view the animation in your browser, save it, or even push it to a Tidbyt device with pixlet push.

Example: A Clock App

This applet accepts a timezone parameter and produces a two frame animation displaying the current time with a blinking ':' separator between the hour and minute components.

load("render.star", "render")
load("time.star", "time")

def main(config):
    timezone = config.get("timezone") or "America/New_York"
    now = time.now().in_location(timezone)

    return render.Root(
        delay = 500,
        child = render.Box(
            child = render.Animation(
                children = [
                    render.Text(
                        content = now.format("3:04 PM"),
                        font = "6x13",
                    ),
                    render.Text(
                        content = now.format("3 04 PM"),
                        font = "6x13",
                    ),
                ],
            ),
        ),
    )

Here's the resulting image:

Example: A Bitcoin Tracker

Applets can get information from external data sources. For example, here is a Bitcoin price tracker:

Read the in-depth tutorial to learn how to make an applet like this.

Push to a Tidbyt

If you have a Tidbyt, pixlet can push apps directly to it. For example, to show the Bitcoin tracker on your Tidbyt:

pixlet render examples/bitcoin.star
pixlet push --api-token <YOUR API TOKEN> <YOUR DEVICE ID> examples/bitcoin.webp

To get the ID and API key for a device, open the settings for the device in the Tidbyt app on your phone, and tap Get API key.

If all goes well, you should see the Bitcoin tracker appear on your Tidbyt:

Comments
  • Ubuntu 22.04.1 LTS libwebp.so.6 issue with pre-canned binaries

    Ubuntu 22.04.1 LTS libwebp.so.6 issue with pre-canned binaries

    Updating an Ubuntu machine to 22.04 leads to issues:

    $ ./pixlet
    ./pixlet: error while loading shared libraries: libwebp.so.6: cannot open shared object file: No such file or directory
    $ ldd pixlet 
    	linux-vdso.so.1 (0x00007ffe4f93f000)
    	libwebpdemux.so.2 => /lib/x86_64-linux-gnu/libwebpdemux.so.2 (0x00007f7f780b2000)
    	libwebpmux.so.3 => /lib/x86_64-linux-gnu/libwebpmux.so.3 (0x00007f7f780a5000)
    	libwebp.so.6 => not found
    	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7f780a0000)
    	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7f77e78000)
    	libwebp.so.7 => /lib/x86_64-linux-gnu/libwebp.so.7 (0x00007f7f77e0a000)
    	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7f77d23000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007f7f780ca000)
    $ ls /lib/x86_64-linux-gnu/libweb*
    /lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37        /lib/x86_64-linux-gnu/libwebpmux.so.3      /lib/x86_64-linux-gnu/libwebrtc_audio_processing.so.1
    /lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37.56.10  /lib/x86_64-linux-gnu/libwebpmux.so.3.0.8  /lib/x86_64-linux-gnu/libwebrtc_audio_processing.so.1.0.0
    /lib/x86_64-linux-gnu/libwebpdemux.so.2              /lib/x86_64-linux-gnu/libwebp.so.7
    /lib/x86_64-linux-gnu/libwebpdemux.so.2.0.9          /lib/x86_64-linux-gnu/libwebp.so.7.1.3
    

    Looks like Ubuntu are now on libwebp 7

  • Push Formats (star)

    Push Formats (star)

    It looks as if the only format the API accepts for the push command is webp. Is it possible to push a star file, and configure the refresh interval on the Tidbyt?

    Example: I’m writing a clock app (as you have in the README example). When I render and push this, the Tidbyt will only display the one image (it does not update automatically when the minute changes). Do I need a server to render and push the star file once every minute to keep the display up to date? OR should I try to build the clock “app” (which is actually just a webp) such that it includes 720 frames (or 1440 frames for 24 hour time)?

  • Push As Installation not working?

    Push As Installation not working?

    I'm referencing the Push As Installation instructions: https://github.com/tidbyt/pixlet#push-as-an-installation

    Just got my Tidbyt today, and I'm trying to write some code that shows my current lifetime solar power production, etc. When I add an Installation ID to my push command, it never shows up in the app on my phone as that Install ID or anything added by API as the instructions show should happen.

    Here's the commands I'm running in a .sh file that I plan to have update daily from a Raspberry Pi and then I'd like it to show up in my rotation.

    pixlet render solarlife.star
    
    pixlet push --api-token <API TOKEN> <DEVICE ID> solarlife.webp Solar
    

    Also tried it in quotes ("Solar") to no avail.

    Is this a known issue?

    Thanks!

  • `brew install`: invalid syntax in tap

    `brew install`: invalid syntax in tap

    Output of brew install:

    brew install tidbyt/tidbyt/pixlet
    ==> Tapping tidbyt/tidbyt
    Cloning into '/opt/homebrew/Library/Taps/tidbyt/homebrew-tidbyt'...
    remote: Enumerating objects: 67, done.
    remote: Counting objects: 100% (67/67), done.
    remote: Compressing objects: 100% (66/66), done.
    remote: Total 67 (delta 41), reused 0 (delta 0), pack-reused 0
    Receiving objects: 100% (67/67), 9.54 KiB | 9.54 MiB/s, done.
    Resolving deltas: 100% (41/41), done.
    Error: Invalid formula: /opt/homebrew/Library/Taps/tidbyt/homebrew-tidbyt/pixlet.rb
    formulae require at least a URL
    Error: Cannot tap tidbyt/tidbyt: invalid syntax in tap!
    

    Other info that might be helpful:

    brew doctor
    Your system is ready to brew.
    
    brew config
    HOMEBREW_VERSION: 3.3.9-36-ge970bb1
    ORIGIN: https://github.com/Homebrew/brew
    HEAD: e970bb18765cd4f16c39585cb0eabc9208c68996
    Last commit: 26 hours ago
    Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
    Core tap HEAD: f2b69fcaf6cf9925caac56dad26d39d30e89b42c
    Core tap last commit: 3 hours ago
    Core tap branch: master
    HOMEBREW_PREFIX: /opt/homebrew
    HOMEBREW_CASK_OPTS: []
    HOMEBREW_CORE_GIT_REMOTE: https://github.com/Homebrew/homebrew-core
    HOMEBREW_EDITOR: code
    HOMEBREW_MAKE_JOBS: 10
    Homebrew Ruby: 2.6.8 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
    CPU: 10-core 64-bit arm_firestorm_icestorm
    Clang: 13.0.0 build 1300
    Git: 2.34.1 => /opt/homebrew/bin/git
    Curl: 7.77.0 => /usr/bin/curl
    macOS: 12.0.1-arm64
    CLT: 13.1.0.0.1.1633545042
    Xcode: 13.1
    Rosetta 2: false
    
  • feat(arm64-support): add arm64 to goreleaser config

    feat(arm64-support): add arm64 to goreleaser config

    hi there! 👋🏻

    I just got my Tidbyt in the mail (yay!) and started playing around. I had to build from source because I'm using an M1 Mac.

    I have a bunch of experience with golang, so I decided to see if I could get things updated to fix this issue https://github.com/tidbyt/pixlet/issues/39

    This PR is an attempt at that 😄

    Notes This adds arm64 to the list of supported go architectures in the goreleaser configuration.

    It also updates the fetch-artifacts.sh script to copy the linux and darwin arm64 artifacts. I'm not entirely sure how this fits into the buildkite CI process, but it seems like it might need to be updated.

    I'm able to run the goreleaser command locally and see it generate all the proper files.

    One interesting and important note about building the render module while running on macos, i did need to set up the CPATH and LIBRARY_PATH as described here https://github.com/tidbyt/pixlet/issues/39#issuecomment-900727783

    fixes #39 (I hope)

  • Support/document installation on ARM

    Support/document installation on ARM

    We've gotten a couple requests now from users with arm and arm64 (Raspberry Pi, Apple M1). The main sticking point seems to be WebP. The library is fairly portable and some users have even managed to install libwebp, but Pixlet still doesn't seem to build.

    • [x] Investigate & resolve blockers for ARM installations.
    • [x] Document how to install on Raspberry Pi.
    • [x] Document how to install on M1.
  • Pls help with install process on windows

    Pls help with install process on windows

    I followed all the steps and it works until I get to "make build". No matter how much I have tried it keeps saying:

    $ make build -bash: make: command not found

    Someone pls help me, this is so stupid I'm losing my mind over it. Also, I have already tried re-installing everything.

  • Sequence widget unavailable in v0.17.6

    Sequence widget unavailable in v0.17.6

    Error: module has no .Sequence field or method

    The Sequence widget isn't making into the module exports. From debug:

    [onebusaway2.star] ["Animation", "Box", "Circle", "Column", "Image", "Marquee", "Padding", "Plot", "Root", "Row", "Stack", "Text", "WrappedText", "fonts"]
    2022/05/19 13:56:14 error loading applet: error running script: Traceback (most recent call last):
      onebusaway2.star:39:22: in main
    Error: module has no .Sequence field or method
    ^C
    $ pixlet version
    Pixlet version: v0.17.6
    
  • `render.WrappedText': Add Option for text alignment

    `render.WrappedText': Add Option for text alignment

    This PR adds the option for text alignment with render.WrappedText.

    I think there should be an additional test in the wrappedtext_test.go file. But is there an easy way to make the image output of what to expect instead of manually doing it?

    As there currently is no change to the testing file. Also not sure if I did the go syntax as it should be.

  • Add additional behaviors to Marquee widget.

    Add additional behaviors to Marquee widget.

    Description

    • Add 'behavior' option:

      • If left empty or set to 'scroll', it results in the existing marquee behavior.
      • If set to 'alternate', the child widget will be scrolled with alternating directions.
      • Attention: 'scroll' does NOT support 'pause_start' and 'pause_midway' options (see below).
      • Attention: 'alternate' does NOT support 'offset_start' and 'offset_end' options.
    • Add 'scroll_always' option:

      • If left empty or set to 'False', it results in the existing marquee behavior.
      • If set to 'True', the child widget will be scrolled even if it fits entirely.
    • Add 'pause_start' and 'pause_midway' options:

      • Both values default to '1', and have a minumum value of '1'.
      • They control how many frames to pause the animation at the start and at the midway point, before changing directions.
    • Add tests for all new options.

    Examples

    behavior = "alternate",
    scroll_direction = "horizontal",
    

    marquee_horizontal_alternate

    behavior = "alternate",
    scroll_direction = "horizontal",
    pause_start = 10,
    pause_midway = 10,
    

    marquee_horizontal_alternate_pause_10

    behavior = "alternate",
    scroll_direction = "horizontal",
    scroll_always = True,
    

    marquee_horizontal_alternate_always

    behavior = "alternate",
    scroll_direction = "vertical",
    

    marquee_vertical_alternate

    behavior = "alternate",
    scroll_direction = "vertical",
    pause_start = 10,
    pause_midway = 10,
    

    marquee_vertical_alternate_pause_10

    behavior = "alternate",
    scroll_direction = "vertical",
    scroll_always = True,
    

    marquee_vertical_alternate_always

    behavior = "scroll",
    scroll_direction = "horizontal",
    scroll_always = True,
    

    marquee_horizontal_scroll_always

  • Fix WrappedText Linespacing

    Fix WrappedText Linespacing

    So am not sure if this is the only thing that is needed to fix #135. But it works for my use case for the fix the vertical scroll in the open PR here.

    Readjusted to fix vertical issue by submitting a PR fix to wrapped text in pixlet.

    Without this merge, the last line will just be cut off, so won't be much different for vertical scroll prior to that PR.

  • fix(deps): update dependency @mui/x-date-pickers to v5.0.13

    fix(deps): update dependency @mui/x-date-pickers to v5.0.13

    Mend Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | @mui/x-date-pickers (source) | 5.0.12 -> 5.0.13 | age | adoption | passing | confidence |


    Release Notes

    mui/mui-x

    v5.0.13

    Compare Source

    Changes
    • [pickers] Fix the product license reference name (#​7367)

    Configuration

    📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Enabled.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

  • fix(deps): update go.starlark.net digest to d7da887

    fix(deps): update go.starlark.net digest to d7da887

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | go.starlark.net | require | digest | 09991d3 -> d7da887 |


    Configuration

    📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Enabled.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

  • Add delay feature to marquee

    Add delay feature to marquee

    Instead of always having to start the marquee off-screen, this allows the text at the beginning of the marquee to be delayed for a specified number of frames.

    Delay is currently set to zero to keep with current behavior, but should it maybe be set to 1 or 2?

    Note this closes #339 that I opened. Example difference from the NationalToday app.

    If this gets merged I can set the delay for this app to maybe one or two instead. but will wait to open a PR in the community repo.

    Before: nationalToday

    After:

    delay=5: nationalToday

    delay=10: nationalToday

  • feat: Add native linter and formatter

    feat: Add native linter and formatter

    Overview

    This change adds in native linting and formatting support to Pixlet by wrapping buildifier with some user friendly CLI flags. The two new commands:

    • pixlet format: Formats pixlet apps with an optional dry run
    • pixlet lint: Lints pixlet apps with an option to automatically fix the issue

    TODOs

    • [ ] Clean up help messages and CLI flags for both commands so they are useful and easy to understand
    • [ ] Clean up default argument behavior so we're not reading from standard in
    • [ ] Clean up error messages to remove buildifier
    • [ ] Test each command with some rigor to ensure they behave as expected
  • 0.22.8 glibc issue

    0.22.8 glibc issue

    Looks like #514 introduced a regression in the Linux binary distribution:

    pixlet: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by pixlet)
    pixlet: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by pixlet)
    

    Downgrading to 0.22.7 works for me.

  • Add support for Image widget to handle a file URL or SVG

    Add support for Image widget to handle a file URL or SVG

    Hi tidbyt team!

    I just got a tidbyt as a gift and I am absolutely loving how configurable it is and that a developer experience has been beautifully built out!

    When I was playing around with writing my first app, I really wanted the ability to support SVG's. As I was writing that piece in my own app code I realized that this library could easily support that out of the box and further I added the ability to do URL as well so pixlet could be even easier than it already is at onboarding developers.

    Hopefully it was ok that I opened this without being attached to an issue, I was trying to find Contributor guidelines but couldn't find much (please let me know if I missed something)

    If there's any changes to syntax/style/etc please let me know, happy to change!

    SVG +URL Example:

    load("render.star", "render")
    
    def main(config):
        return render.Root(
            child=render.Image(src="https://www.svgrepo.com/download/374110/svg.svg")
        )
    

    Screenshot 2022-12-01 at 1 36 55 PM

Related tags
Example of how to achieve pixel perfect shadows in a 2D view
Example of how to achieve pixel perfect shadows in a 2D view

Lights and Shadows Example of how to achieve pixel perfect shadows in a 2D view. The sample is based on the following sources: 2D Pixel Perfect Shadow

Oct 26, 2022
The android-go project provides a platform for writing native Android apps in Go programming language.
The android-go project provides a platform for writing native Android apps in Go programming language.

android-go The android-go project aims to provide a platform (namely an SDK) for writing native Android apps in Go programming language. All things he

Jan 5, 2023
A phoenix Chain client based on the go-ethereum fork,the new PoS consensus engine is based on the VRF algorithm.

Phoenix Official Golang implementation of the Phoenix protocol. !!!The current version is for testing and developing purposes only!!! Building the sou

Aug 18, 2022
Geocache is an in-memory cache that is suitable for geolocation based applications.
Geocache is an in-memory cache that is suitable for geolocation based applications.

geocache geocache is an in-memory cache that is suitable for geolocation based applications. It uses geolocation as a key for storing items. You can s

Oct 27, 2022
This is old and unmaintained code, ignore it. starfish is a simple, SDL based, 2D graphics and user input library for Go. If you intend to work on it, please fork from the 'devel' branch, not 'master'. Current release: 0.12.0

What is starfish? What starfish is: starfish is a simple 2D graphics and user input library for Go built on SDL. What starfish is not: While it is bui

Jun 4, 2019
A Grid based 2D Graphics library
A Grid based 2D Graphics library

gridder Built on top of Go Graphics github.com/fogleman/gg with the idea to simplify visualizing Grids using 2D Graphics. Dependencies gg github.com/f

Dec 1, 2022
Gorched is terminal based game written in Go inspired by "The Mother of all games" Scorched Earth

Gorched Gorched is terminal based game written in Go inspired by "The Mother of all games" Scorched Earth. How the game looks like depends on your ter

Dec 13, 2022
Canvas is a Go drawing library based on OpenGL or using software rendering that is very similar to the HTML5 canvas API
Canvas is a Go drawing library based on OpenGL or using software rendering that is very similar to the HTML5 canvas API

Go canvas Canvas is a pure Go library that provides drawing functionality as similar as possible to the HTML5 canvas API. It has nothing to do with HT

Jan 3, 2023
A Go skia binding based on skia C library through cgo

go-skia is a Go skia binding based on skia C library through cgo. Note: the project is still in early stage, and it only supports Linux-amd64 now. The

Nov 7, 2022
Boundary enables identity-based access management for dynamic infrastructure.
Boundary enables identity-based access management for dynamic infrastructure.

Boundary Please note: We take Boundary's security and our users' trust very seriously. If you believe you have found a security issue in Boundary, ple

Jan 9, 2023
A simple API written in Go that creates badges in SVG format, based on the requested route.

A simple API written in Go that creates badges in SVG format, based on the requested route. Those graphics can be used to style README.md files, or to add tags to webpages.

Jul 2, 2021
A simple javascript website that takes user input, queries a Go based backend which then creates ascii art and sends it back to the frontend

A simple javascript website that takes user input, queries a Go based backend which then creates ascii art and sends it back to the frontend. Finally the site displays the ascii art and offers the option to download as multiple file types.

Jan 7, 2022
Faster than the fastest in the world pixel-by-pixel image difference tool.

imgdiff Faster than the fastest in the world pixel-by-pixel image difference tool. Why? imgdiff isn't as fast as a tool like this should be and I'm no

Dec 21, 2022
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.

Beaver A Real Time Messaging Server. Beaver is a real-time messaging server. With beaver you can easily build scalable in-app notifications, realtime

Jan 1, 2023
Example of how to achieve pixel perfect shadows in a 2D view
Example of how to achieve pixel perfect shadows in a 2D view

Lights and Shadows Example of how to achieve pixel perfect shadows in a 2D view. The sample is based on the following sources: 2D Pixel Perfect Shadow

Oct 26, 2022
Comparison of Pixel and Ebiten API on the trees tutorial

Rewriting the trees tutorial of Pixel with Ebiten for API comparison I tried Pixel and really liked the clean API but the dev seems to be on pause sin

Dec 7, 2021
Caps - Attempt at making computer generated pixel art from bottle caps
Caps - Attempt at making computer generated pixel art from bottle caps

I started sorting the caps and realised that there are significantly more Alexan

Mar 9, 2022
A golang implementation of the Open Pixel Control protocol

__ ___ ___ _____ ___ /'_ `\ / __`\ _______ / __`\/\ '__`\ /'___\ /\ \L\ \/\ \L\ \/\______\/\ \L\ \ \ \L\ \/\ \__/ \ \

Jul 3, 2022
Stonks is a terminal based stock visualizer and tracker that displays realtime stocks in graph format in a terminal.
Stonks is a terminal based stock visualizer and tracker that displays realtime stocks in graph format in a terminal.

Stonks is a terminal based stock visualizer and tracker. Installation Requirements: golang >= 1.13 Manual Clone the repo Run make && make install Pack

Dec 16, 2022
A lightweight job scheduler based on priority queue with timeout, retry, replica, context cancellation and easy semantics for job chaining. Build for golang web apps.

Table of Contents Introduction What is RIO? Concern An asynchronous job processor Easy management of these goroutines and chaining them Introduction W

Dec 9, 2022