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 🙏

© 2026 – Pkg Stats / Ryan Hefner

fiber-htmx

v1.0.2

Published

Components for building modern web applications with htmx

Readme

🔨 HTMX

Test & Build Go Reference Go Report Card License: MIT Taylor Swift

A Go package to write HTML5 and HTMX components in Go. The package is designed to work with fiber and htmx.

🦄 Features

  • Write declartive HTML5 components in Go without using templates and with the full-power of a type-safe language, auto-completion, and refactoring.
  • Full support for HTMX components.
  • No dependencies on JavaScript frameworks.
  • Fast rendering of HTML5 and HTMX components.
  • Easy to use and learn.
  • Easy to extend and customize.

✨ Components

There are additional complex components that help to write HTML5 and HTMX components in Go.

🛸 Installation

go get github.com/katallaxie/fiber-htmx

The available web components are published in the fiber-htmx package.

htmx.HTML5(
    htmx.HTML5Props{
        Head: []htmx.Node{
            htmx.Script(
                htmx.Src("https://unpkg.com/[email protected]"),
            ),
            htmx.Link(
                htmx.Rel("stylesheet"),
                htmx.Href("https://unpkg.com/[email protected]/dist/out.css"),
            ),
        },
    },
    htmx.Body(
        htmx.ClassNames{},
        htmx.Toasts(),
    ),
)

🧪 Sample Use

Creating a button leveraging htmx is as easy as this.

htmx.Button(
    htmx.Attribute("type", "submit")
    htmx.Text("Button"),
    htmx.HxPost("/api/respond")
)

🎨 Elements

HTML and HTMX elements are represented as functions in Go. The functions are used to create the elements.

htmx.Div(
    htmx.ClassNames{
        tailwind.FontSemibold: true,
    },
    htmx.Text("Hello World"),
)

This will create the following HTML element.

<div class="font-semibold">Hello World</div>

There is support for all HTML5 elements and Tailwind classes. Use import "github.com/katallaxie/fiber-htmx/tailwind" to include Tailwind classes.

📦 Components

Write HTML5 and HTMX components in Go.

func HelloWorld() htmx.Node {
    return htmx.Div(
        htmx.ClassNames{
            "font-semibold",
        },
        htmx.Text("Hello World"),
    )
}

There are different types of composition. For example, passing children to a component.

func HelloWorld(children ...htmx.Node) htmx.Node {
    return htmx.Div(
        htmx.ClassNames{
            "font-semibold",
        },
        htmx.Text("Hello World"),
        htmx.Div(
            htmx.ClassNames{
                "text-red-500",
            },
            htmx.Group(children...),
        ),
    )
}

Styling of components is done with the htmx.ClassNames type.

func HelloWorld() htmx.Node {
    return htmx.Div(
        htmx.ClassNames{
            tailwind.FontSemibold: true,
            "text-red-500": true,
        },
        htmx.Text("Hello World"),
    )
}

There are also helpers to make the life with styling easier by merging classes.

func HelloWorld(classes htmx.ClassNames) htmx.Node {
    return htmx.Div(
        htmx.Merge(
            htmx.ClassNames{
                "font-semibold",
                "text-red-500",
            },
            classes,
        )
        htmx.Text("Hello World"),
    )
}

There is alos another pattern to create a component. This enables you to track state and to use the component in a more declarative way.

type Page struct {
	htmx.Node
}

func NewPage(title, body string) *Page {
	return &Page{
		Node: htmx.HTML5(
			htmx.HTML5Props{
				Title: title,
			},
			htmx.Body(
				htmx.Div(
					htmx.Text(body),
				),
			),
		),
	}
}

There is also the option to use htmx.Controller to encapsulate the logic of the components.


func NewHelloWorldController() htmx.ControllerFactory {
  return func() htmx.Controller {
    return &NewHelloWorldController{}
  }
}

type HelloWorldController struct {
    htmx.DefaultController
}

func (c *HelloWorldController) Get() error {
    return c.Render(
      htmx.HTML5(
            htmx.HTML5Props{
                Title:    "index",
                Language: "en",
                Head: []htmx.Node{},
            },
            htmx.Div(
                htmx.ClassNames{},
                htmx.Text("Hello World"),
            ),
        ),
    )    
}

app := fiber.New()
app.Get("/", htmx.NewHxControllerHandler(NewHelloWorldController()))

app.Listen(":3000")

🧩 Import map

An import map is a JSON object that allows developers to control how the browser resolves module specifiers when importing JavaScript modules.

htmx.Imports(
    htmx.ImportsProp{
        Resolver: cache.New(jsdeliver.New()),
        Pkgs: []imports.ExactPackage{
            {
                Name:    "htmx.org",
                Version: "2.0.4",
            },
        },
        Requires: []imports.Require{
            {
                File: "dist/htmx.esm.js",
            },
        },
    }
),

Import maps let you import JavaScript modules using logical names that map to versioned/digested files – directly from the browser. So you can build modern JavaScript applications using JavaScript libraries made for ES modules (ESM) without the need for transpiling or bundling. This frees you from needing Webpack, Yarn, npm, or any other part of the JavaScript toolchain. All you need is the asset pipeline that's already included in Rails.

🏄‍♀️ Icons

The package has support for Heroicons. The support is for the outline and solid icons.

icon := heroicons.AcademicCapOutline(heroicons.IconProps{})
icon.Render(os.Stdout)

🧑‍🎤 Live Reload

Air is a live reloading tool for Go applications. It watches your files and reloads the application when changes are detected.

fiber-reload is a package that enables live reloading for fiber applications.

app := fiber.New()
app.Use(reload.Environment(reload.Development))
reload.WithHotReload(app)

In the application the reload script needs to be added.

htmx.Script(
  htmx.Src("https://unpkg.com/[email protected]/reload.js"),
  htmx.Type("text/javascript"),
),

This reloads the application as the server is restart on file changes. See examples.

🧑‍💻 VSCode and Copilot

  1. Run this command to save the llms.txt to .vscode/htmx.md
curl -L https://raw.githubusercontent.com/katallaxie/fiber-htmx/refs/heads/main/llms.txt --create-dirs -o .vscode/htmx.md
  1. In .vscode/settings.json Add this:
{
  "github.copilot.chat.codeGeneration.instructions": [
    {
      "file": "./.vscode/htmx.md"
    }
  ]
}

Server-side events (SSE)

The package supports server-side events (SSE) to update the components on the client-side.

manager := sse.NewBroadcastManager(5)
app.Get("/sse", sse.NewSSEHandler(manager))

🛑 Error Handling

There are components that enable handling fallbacks in case of errors and to recover from panics in rendering components.

htmx.Fallback(
  htmx.ErrorBoundary(
    func() htmx.Node {
      return utils.Panic(errors.New("panic"))
    },
  ),
  htmx.Text("Fallback"),
),

📄 Examples

See examples to understand the provided interfaces.

🏎️ Benchmarks

BenchmarkElement-10                     12964440                77.40 ns/op
Benchmark_AttrRender-10                 16038232                74.15 ns/op
Benchmark_HTML5_Render-10                   1392            847193 ns/op
Benchmark_ClassNames_Render-10           3166761               378.2 ns/op

Rendering 10.000 nodes took >0.8ms. The package is fast enough to render HTML5 and HTMX components.

License

MIT