Skip to content

Instantly share code, notes, and snippets.

Northstar Tutorial: Building Modern Web Apps with Go and Datastar

This tutorial will guide you through understanding and building features in Northstar, a modern web application stack combining Go, NATS, Datastar, and Templ. It's designed for developers new to Go or the hypermedia/reactive patterns that Datastar enables.

Table of Contents

  1. Understanding the Stack
  2. Core Concepts
  3. Project Architecture
  4. Building Your First Feature

Northstar Tutorial: Building Modern Web Apps with Go and Datastar

This tutorial will guide you through understanding and building features in Northstar, a modern web application stack combining Go, NATS, Datastar, and Templ. It's designed for developers new to Go or the hypermedia/reactive patterns that Datastar enables.

Table of Contents

  1. Understanding the Stack
  2. Core Concepts
  3. Project Architecture
  4. Building Your First Feature
@keyurshah
keyurshah / datastar-llms.md
Created November 20, 2025 22:09 — forked from Yacobolo/datastar-llms.md
web scrape of https://data-star.dev/docs - includes table of the contents with line number and section len so an llm can use read tool using offset and limit. This helps to save tokens.

Guide

Getting Started

Datastar simplifies frontend development, allowing you to build backend-driven, interactive UIs using a hypermedia-first approach that extends and enhances HTML.

Datastar provides backend reactivity like htmx and frontend reactivity like Alpine.js in a lightweight frontend framework that doesn’t require any npm packages or other dependencies. It provides two primary functions:

  1. Modify the DOM and state by sending events from your backend.
  2. Build reactivity into your frontend using standard data-* HTML attributes.
# Function to print the current state of the board
def print_board(board):
# Iterate over the board in steps of 3 to print each row
for i in range(1, 10, 3):
# Print the current row of the board with corresponding values
print(f"{i}: {board[i]} {i+1}: {board[i+1]} {i+2}: {board[i+2]}\n")
# Function to check if there's a winner
def check_win(board):
# Define all possible winning combinations
# Function to print the current state of the board
def print_board(board):
# Iterate over the board in steps of 3 to print each row
for i in range(1, 10, 3):
# Print the current row of the board with corresponding values
print(f"{i}: {board[i]} {i+1}: {board[i+1]} {i+2}: {board[i+2]}\n")
# Function to check if there's a winner
def check_win(board):
# Define all possible winning combinations
<?php
/**
* @copyright Copyright (c) PutYourLightsOn
*/
/**
* Blitz config.php
*
* This file exists only as a template for the Blitz settings.
@keyurshah
keyurshah / boost.unpoly.js
Created June 5, 2020 17:14 — forked from johndwells/boost.unpoly.js
Automatically pass all same-domain links through unpoly.js
// Automatically bind internal links to `up-follow` behaviour
// Unpoly will already catch and handle links with explicit `up-follow` etc,
// so we are safe to assume that if our handler below is triggered, the link
// doesn't already have an up- attribute.
//
// Scenarios to handle:
// Hat-tip to https://github.com/instantpage/instant.page/blob/master/instantpage.js
// ✅ cmd+click
// ✅ empty links
// ✅ links to another domain
@keyurshah
keyurshah / trix.blade.php
Created May 15, 2020 13:43 — forked from tanthammar/trix.blade.php
Livewire trix input
@push('body-styles')
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/trix/1.2.0/trix.css">
@endpush
<form>
<input x-ref="description" id="description" name="description" value='{{ $description }}' type="hidden" />
<div wire:ignore>
<trix-editor input="description"></trix-editor>
</div>
@keyurshah
keyurshah / LivewireSortable.php
Created May 15, 2020 13:42 — forked from tanthammar/LivewireSortable.php
Livewire Sortable fix with array form
<?php
namespace App\Http\Livewire\App\Organizers\Forms;
use App\Http\Livewire\Traits\Form;
use App\Models\Organizer;
use Livewire\Component;
class People extends Component
{
@keyurshah
keyurshah / test.log
Created January 15, 2020 04:22
AlpineJS Errors
FAIL test/lifecycle.spec.js
● callbacks registered within x-created can affect reactive data changes
expect(received).toEqual(expected) // deep equality
Expected: "baz"
Received: undefined
51 | Alpine.start()
52 |