adnaan / gomodest-starter

A complex SAAS starter kit using Go, the html/template package, and sprinkles of javascript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GOMODEST is a Multi Page App(MPA) starter kit using Go's html/template, SvelteJS and StimulusJS. It is inspired from modest approaches to building webapps as enlisted in


I am a devops engineer who dabbles in UI for side projects, internal tools and such. The SPA/ReactJS ecosystem is too costly for me. This is an alternative approach.

The main idea is to use server rendered html with spots of client-side dynamism using SvelteJS & StimulusJS

The webapp is mostly plain old javascript, html, css but with sprinkles of StimulusJS & spots of SvelteJS used for interactivity sans page reloads. StimulusJS is used for sprinkling interactivity in server rendered html & mounting Svelte components into divs.


A few things which were used:

  1. Go, html/template, goview,
  2. Authentication:
  3. SvelteJS
  4. Hotwire
  5. Bulma CSS

Many more things in go.mod & web/package.json

To run, clone this repo and:

$ make install
# another terminal
$ make run-go

The ideas in this starter kit follow the JS gradient as noted here. I have taken the liberty to organise them into the following big blocks: server-rendered html, sprinkles and spots.

Server Rendered HTML

Use html/template and goview to render html pages. It's quite powerful when do you don't need client-side interactions.


func accountPage(w http.ResponseWriter, r *http.Request) (goview.M, error) {

	session, err := store.Get(r, "auth-session")
	if err != nil {
		return nil, fmt.Errorf("%v, %w", err, InternalErr)

	profileData, ok := session.Values["profile"]
	if !ok {
		return nil, fmt.Errorf("%v, %w", err, InternalErr)

	profile, ok := profileData.(map[string]interface{})
	if !ok {
		return nil, fmt.Errorf("%v, %w", err, InternalErr)

	return goview.M{
		"name": profile["name"],
	}, nil



Use stimulusjs to level up server-rendered html to handle simple interactions like: navigations, form validations etc.


    <button class="button is-primary is-outlined is-fullwidth"
            data-goto="/  "
        if (e.currentTarget.dataset.goto){
            window.location = e.currentTarget.dataset.goto;


Use sveltejs to take over spots of a server-rendered html page to provide more complex interactivity without page reloads.

This snippet is the most interesting part of this project:

{{define "content"}}
    <div class="columns is-mobile is-centered">
        <div class="column is-half-desktop">


In the above snippet, we use StimulusJS to mount a Svelte component by using the following code:

     import { Controller } from "stimulus";
     import components from "./components";
     export default class extends Controller {
         static targets = ["component"]
         connect() {
             if (this.componentTargets.length > 0){
                 this.componentTargets.forEach(el => {
                     const componentName = el.dataset.componentName;
                     const componentProps = el.dataset.componentProps ? JSON.parse(el.dataset.componentProps): {};
                     if (!(componentName in components)){
                         console.log(`svelte component: ${componentName}, not found!`)
                     const app = new components[componentName]({
                         target: el,
                         props: componentProps


This strategy allows us to mix server rendered HTML pages with client side dynamism.

Other possibly interesting aspects could be the layout of web/html and the usage of the super nice goview library to render html in these files:

  1. router.go
  2. view.go
  3. pages.go

That is all.




A complex SAAS starter kit using Go, the html/template package, and sprinkles of javascript.

License:MIT License


Language:Go 69.3%Language:HTML 22.7%Language:JavaScript 5.8%Language:Svelte 1.6%Language:Dockerfile 0.2%Language:Makefile 0.2%Language:SCSS 0.1%