go_ssr

package module
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2025 License: MIT Imports: 25 Imported by: 0

README

gotossr

Build Go powered React web apps with server-side rendering.


Go Report GoDoc MIT License

gotossr is a drop in plugin to any existing Go web framework to allow server rendering React. It's powered by esbuild and allows for passing props from Go to React with type safety.

Forked from natewong1313/go-react-ssr

What's New

  • V8 Runtime Support - 70-85% faster than QuickJS
  • Runtime Pooling - Reuse JS runtimes for better performance
  • Redis Cache - Optional distributed cache for multi-server deployments
  • Graceful Shutdown - Clean resource cleanup
  • Build Tags - Minimize dependencies in production (2 deps only)
  • Reduced Dependencies - Replaced zerolog/jsonparser with stdlib

📜 Features

  • Lightning fast compiling with esbuild
  • V8 or QuickJS runtime (selectable)
  • Auto generated Typescript structs for props
  • Hot reloading in development
  • Simple error reporting
  • Production optimized with build tags
  • Drop in to any existing Go web server

🛠️ Getting Started

⚡️ Using the CLI tool

$ go install github.com/yejune/gotossr-cli@latest
$ gotossr-cli create

See gotossr-cli for more details.

📝 Add to existing web server

$ go get -u github.com/yejune/gotossr
import gossr "github.com/yejune/gotossr"

engine, err := gossr.New(gossr.Config{
    AppEnv:             "development", // or "production"
    AssetRoute:         "/assets",
    FrontendDir:        "./frontend/src",
    GeneratedTypesPath: "./frontend/src/generated.d.ts",
    PropsStructsPath:   "./models/props.go",
})
g.GET("/", func(c *gin.Context) {
    response := engine.RenderRoute(gossr.RenderConfig{
        File:  "Home.tsx",
        Title: "Example app",
        Props: &models.IndexRouteProps{
            InitialCount: rand.Intn(100),
        },
    })
    c.Writer.Write(response)
})

⚡ Performance

Runtime Build Tag Performance
QuickJS (default) Good
V8 -tags=use_v8 70-85% faster

🏗️ Build Tags

Build Command Runtime Dependencies
go build QuickJS 5
go build -tags=use_v8 V8 5
go build -tags=prod QuickJS 2
go build -tags="prod,use_v8" V8 2

🚀 Deploying to production

go build -tags="prod,use_v8" -ldflags "-w -s" -o main .

Example Dockerfile:

FROM golang:1.24-alpine as build-backend
RUN apk add --no-cache git build-base
ADD . /build
WORKDIR /build
RUN go mod download
RUN CGO_ENABLED=1 GOOS=linux go build -tags="prod,use_v8" -ldflags "-w -s" -o main .

FROM node:20-alpine as build-frontend
ADD ./frontend /frontend
WORKDIR /frontend
RUN npm install

FROM alpine:latest
RUN apk add --no-cache libstdc++ libgcc
COPY --from=build-backend /build/main ./app/main
COPY --from=build-frontend /frontend ./app/frontend
WORKDIR /app
EXPOSE 8080
CMD ["./main"]

📄 License

MIT License - see LICENSE for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	AppEnv              string            // "production" or "development"
	AssetRoute          string            // The route to serve assets from, e.g. "/assets"
	FrontendDir         string            // The path to the frontend folder, where your React app lives
	GeneratedTypesPath  string            // The path to the generated types file
	PropsStructsPath    string            // The path to the Go structs file(s), comma-separated for multiple files
	LayoutFilePath      string            // The path to the layout file, relative to the frontend dir
	LayoutCSSFilePath   string            // The path to the layout css file, relative to the frontend dir
	TailwindConfigPath  string            // The path to the tailwind config file
	HotReloadServerPort int               // The port to run the hot reload server on, 3001 by default
	JSRuntimePoolSize   int               // The number of JS runtimes to keep in the pool, 10 by default
	CacheConfig         cache.CacheConfig // Cache configuration (local or redis)
	ClientAppPath       string            // Path to client SPA app (e.g., "App.tsx") for client-side routing after hydration
	// SPA hydration mode options (only used when ClientAppPath is set):
	// - "router": wraps with StaticRouter/BrowserRouter for true hydration (default, requires react-router-dom)
	// - "replace": uses createRoot to replace SSR HTML (no hydration, compatible with any SPA structure)
	SPAHydrationMode string // "router" or "replace", defaults to "router"
	// External JS file options (for browser caching optimization):
	// When StaticJSDir is set, JS bundles are written to files instead of inlined in HTML.
	// This enables browser caching - the React library bundle rarely changes and can be cached.
	StaticJSDir string // Directory to write JS files (e.g., "frontend/dist/assets"). If empty, JS is inlined.
	IsDev       bool   // Development mode - enables hot reload, disables caching

	// Generators are custom code generators that run during engine initialization (dev mode only)
	// Use this to generate routes, API clients, or any other code based on the SSR configuration
	Generators []Generator
}

Config is the config for starting the engine

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the config

type Engine

type Engine struct {
	Logger                  *slog.Logger
	Config                  *Config
	HotReload               *HotReload
	Cache                   cache.Cache
	RuntimePool             *jsruntime.Pool
	CachedLayoutCSSFilePath string
	CachedClientSPAJS       string // Cached client SPA bundle JS
	CachedServerSPAJS       string // Cached server SPA bundle JS (for StaticRouter rendering)
	CachedServerSPACSS      string // Cached server SPA bundle CSS
}

func New

func New(config Config) (*Engine, error)

New creates a new gossr Engine instance

func (*Engine) BuildLayoutCSSFile

func (engine *Engine) BuildLayoutCSSFile() error

BuildLayoutCSSFile builds the layout css file if it exists

func (*Engine) IsProduction

func (engine *Engine) IsProduction() bool

IsProduction returns true if running in production mode

func (*Engine) RenderRoute

func (engine *Engine) RenderRoute(renderConfig RenderConfig) []byte

RenderRoute renders a route to html

func (*Engine) Shutdown

func (engine *Engine) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the engine and releases all resources. It should be called when the server is shutting down. The context can be used to set a timeout for the shutdown.

type Generator added in v1.0.4

type Generator interface {
	// Generate is called during engine initialization (dev mode only)
	// config contains all SSR configuration including props paths
	Generate(config *Config) error
}

Generator interface for custom code generation Implementations can generate routes, API clients, or any other code based on the SSR configuration

type HotReload

type HotReload struct {
	// contains filtered or unexported fields
}

func (*HotReload) Start

func (hr *HotReload) Start()

Start starts the hot reload server and watcher

type RenderConfig

type RenderConfig struct {
	File        string
	Title       string
	MetaTags    map[string]string
	Props       interface{}
	RequestPath string // Current request URL path for SPA routing (e.g., "/board/1")
}

RenderConfig is the config for rendering a route

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL