Goship
Opinionated Go + HTMX framework for shipping production apps fast ⛵️
Install / Use
/learn @leomorpho/GoshipREADME
GoShip: Ship in Record Time ⛵️🛟⚓️📦
A Go + HTMX boilerplate with all the essentials for your SaaS, AI tools, or web apps. Start earning online quickly without the hassle.
🎯 The goal of this project is to build the most comprehensive Go-centric OSS starter boilerplate to ship projects fast.
<!-- [](https://goreportcard.com/report/github.com/mikestefanello/pagoda) --> <p align="center"><img alt="Logo" src="https://goship-static.s3.us-west-002.backblazeb2.com/assets/goship.png" height="200px"/></p> <p align="center"> <a href="http://www.youtube.com/watch?feature=player_embedded&v=Mnti8f-4bp0" target="_blank"><img src="https://goship-static.s3.us-west-002.backblazeb2.com/assets/git-repo-video-overview-frame.jpg" alt="Rapid walktrough of project" style="max-width: 100%; height: auto; border: 10px;" /></a> </p> <p style="text-align:center;">Check out the video above for a rapid walkthrough of the project! 🏂</p>This started as a fork of pagoda, for which I am super grateful! Big shoutout to Mike Stefanello and team!
<p align="center"><img alt="Logo" src="https://user-images.githubusercontent.com/552328/147838644-0efac538-a97e-4a46-86a0-41e3abdf9f20.png" height="100px"/></p>Getting Started
Make sure you have make and Golang installed on your machine.
To get up and running with GoShip:
# The below command will:
# - set up the postgres/redis/mailer containers
# - build the JS/CSS assets
# - seed the DB with test users
# - start the project in watch mode
make init
# Running init will fully scrap your state and start with fresh new containers.
# After running `make init` the first time, just use the below for everyday work.
make watch
For in-depth info on the architecture of the project, please see the mikestefanello/pagoda repo. There are some key differences, but since this was originally a fork, 99% of it still applies. I am working on creating clear and actionable documentation, but that is quite time-consuming, so don't hold your socks.
Motivation
Build the same rich interfaces you would build with Javascript frameworks, but with HTML and Go. Limit the number of tools you use. Develop rapidly.
Why the Hell Do We Need Another Boilerplate?
Well, I noticed that there were none for Go. Now, I know most Go folks like to build it all themselves. And while I love doing that myself, I have many project ideas for which I just want to build that specific project, not the entire infra surrounding it, like auth, notifications, payments, file uploads etc. This project has served me well in bringing to production many projects so far. It has evolved far beyond what I originally planned for, though there is still so much potentional to expand on and implement for.
If you'd like a no-nonesense (or not too much?) starter kit to get your next project to production ASAP, while also using awesome technologies like Go, you've found a suitable starting point!
Warning alert! this project is in active development as I am adding things after first trying them out in prod for Chérie, a relationship app to grow your couple. Note that I would welcome any help to develop this boilerplate ❤️.
Features && Tech Stack
See goship.run.
Documentation (WIP)
File Structure
|-- cmd
| |-- web # Web server
| |-- worker # Async worker
| |-- seed # Seeder
|-- config # Config files where the non-secret config vars are stored and the config go struct is defined
|-- pkg # Package imports
| |-- context # Context package to handle context across the app
| |-- controller # Controller package to handle requests and responses
| |-- domain # Domain objects that are used throughout the app, these should be specific to your app/project
| |-- funcmap # Custom template functions
| |-- htmx # HTMX lifecycle helpers
| |-- middleware # Middleware for the app
| |-- repos # Repositories
| |-- routes # Think of these as the controllers in a traditional MVC framework
| |-- services # Services on the Container struct
| |-- tasks # Task definitions
| |-- tests # Utility functions for testing
| |-- types # Struct types
|-- templates # HTML templates
|-- ent # Ent ORM, contains the schema for the DB as well as the generated code from the schema. Always commit this to git.
# Everything else is not Go-specific
|-- deploy.yml # Kamal deployment file
|-- docker-compose.yml # Docker compose file for running the project locally with Docker Desktop
|-- e2e_tests # Playwright E2E tests
|-- scripts # Useful scripts
|-- static # Static files
|-- javascript # Any javascript app can be dropped here. JS and CSS will be built and bundled into a single file. It is currently set up solely for Vanilla JS and Svelte.
|-- build.mjs # Build script for the JS defined in `./javascript`
|-- .env # Secret environment variables
|-- .kamal # Kamal hooks you can use to run commands in the project during deployment
|-- .github # Github actions and secrets
|-- .gitignore # Files to ignore when committing
|-- tailwind.config.js # Tailwind config
|-- tsconfig.json # Typescript config
|-- Procfile # Defines the commands to run the project in watch mode
|-- service-worker.js # Service worker for the PWA
|-- pwabuilder-ios-wrapper # PWA iOS wrapper. Use as a guide for push notifications.
Makefile
The Makefile is the main entry point for the project. It is used to build the project, run the project, and deploy the project.
The following commands are the most useful ones:
make init # Initializes the project
make watch # Runs the project in watch mode, rebuilding assets as you go (JS, CSS, Templ, etc)
make test # Runs the tests
make e2eui # Runs the interactive e2e tests with Playwright #
make cover # Shows a Go coverage report of the tests
# DB specific commands
make ent-new name=YourModelName # Creates a new ent schema file
make makemigrations # Creates a new migration file
make ent-gen # Generates the ent code from the schema
make migrate # Applies migrations
make inspecterd # Shows you a view of all your tables in a UI
make schema
# Docker commands
make up # Starts the docker containers
make down # Stops the docker containers
make down-volume # Stops the docker containers and removes the volumes
make reset # Stops the docker containers and removes the volumes, then rebuilds the docker containers
# Assets
make build-js # Builds the JS assets
make watch-js # Watches the JS assets and rebuilds them on change
make build-css # Builds the CSS assets
make watch-css # Watches the CSS assets and rebuilds them on change
# Worker commands
make worker # Starts the worker
make worker-ui # Will open the terminal to the asynq worker UI
# Stripe (payments)
make stripe-webhook # Sets up a webhook for stripe for local testing
make help # Shows all the commands you can run
General Architecture
For in-depth info on the architecture of the project, please see the mikestefanello/pagoda repo. There are some key differences, but since this was originally a fork, 99% of it still applies.
The most important aspects to note are:
- The
Containerstruct is instantiated when the app starts up and is used to pass dependencies around the app, specifically core services likeLogger,Database,ORM,Cache, etc. - Routes are defined in
routes/routes.goand are registered to theEchoframework. Generally, any logic that alters the DB should be done in thereposlayer so that it is easily testable, and can be used by other routes. A route will generally have aComponent, which is a Templ component defined intemplates/pages/that represents the view.
Database
The current options are:
- Standalone Postgres DB (which you can host anywhere, including locally with Docker)
- Embedded SQLite DB (which is great for small projects and local development)
Starting DB State
To get a look at what tables are available to start off, you can run
make schema
or go to ent/schema and see the declared schemas. Note that ent generates a lot of code. Do not remove it from git. In fact, make sure to keep it there.
To create a new schema, do:
make ent-new name=YourSchemaName
Then generate the migrations
make makemigrations
Then generate the ent generated code to interact with your new schema in Go:
make ent-gen
To apply the migrations, either run make migrate or do a make reset to start from scratch (often times easier, and your test DB should be treated as disposable).
Add a route
Create a new file in routes/ and add your route. A route is a standard Echo handler with some added goodies. Once you've added handlers for your route, you can hook it up to the router in routes/routes.go, where the route should be registered to be reachable from the web.
Set Action Messages
Following an action (POST/DELETE/GET/etc), a msg can be shown to the user. For example, a success message can shown with msg.Success("An email confirmation was sent!") upon user registration. The following message types are currently available:
- success
- info
- warning
- danger
See pkg/repos/msg/msg.go for more info.
Realtime and Notifications
The
Related Skills
tmux
351.4kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
xurl
351.4kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
diffs
351.4kUse the diffs tool to produce real, shareable diffs (viewer URL, file artifact, or both) instead of manual edit summaries.
blogwatcher
351.4kMonitor blogs and RSS/Atom feeds for updates using the blogwatcher CLI.
