# Lura: a Go framework for assembling API gateways with middlewares

> Lura is the Linux Foundation hosted Go library behind KrakenD. It gives you the proxy, router and middleware pieces to build an aggregating gateway, but it is not a gateway binary you download and run.

**luraproject/lura** — Ultra performant API Gateway with middlewares. A project hosted at The Linux Foundation

- Repository: https://github.com/luraproject/lura
- Website: https://luraproject.org
- Stars: 6,798 · Forks: 582
- Language: Go
- License: NOASSERTION
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/luraproject-lura

## The problem Lura solves: many backends, one client-shaped endpoint

A mobile or web client often needs data that lives in several backend services. The README walks through a concrete case: a front page that needs api.store.server/products, api.store.server/marketing-promos, api.users.server/users/{id_user} and api.users.server/shopping-cart/{id_user}. Four round trips, four payloads, and the client picks out the few fields it actually renders. Lura exists to collapse that into one call, lura.server/frontpage/{id_user}, with the gateway doing the fan-out and the trimming.

The intended audience is Go developers building that layer themselves, or teams reusing the components inside a larger application. The README is explicit that this repository is the framework source, not a product: use it if you want to build your gateway from source, or if you want to reuse the components elsewhere. Anyone who wants a working gateway is told to download the KrakenD binary or build KrakenD CE. That split is the single most important thing to understand before reading further, because it decides whether Lura is the right dependency for you at all.

## How the framework is put together: parsers, factories and a router

The repository layout maps onto the pipeline. The config package holds the parser that reads a JSON configuration file. The proxy package contains the default proxy factory, which does the request forwarding and response aggregation. The router package contains adapters for several HTTP routers, and the go.mod file lists which ones the module depends on: gin, chi, gorilla/mux, httptreemux and negroni. The transport directory holds HTTP client and server pieces, including a plugin mechanism, and the encoding, logging and sd directories cover serialisation, logging and service discovery.

The wiring is factory-based rather than configuration-driven at the code level. In the README example, a config.NewParser() parses the file into a serviceConfig, then gin.DefaultFactory(proxy.DefaultFactory(logger), logger) builds a router factory that receives the proxy factory and the logger. Calling New().Run(serviceConfig) on that factory starts the service. Swapping gin for another supported router means swapping the router factory call, not rewriting the proxy logic. That is the Unix-philosophy claim in the README made concrete: small independent components combined by the application author.

The configuration file itself is documented separately in docs/CONFIG.md, and the component breakdown lives in docs/OVERVIEW.md. The README does not reproduce either, so the shape of the aggregation rules, the endpoint definitions and the backend declarations has to be read from those files rather than inferred from the README.

## Installing Lura and running a first proxy

Lura is a Go module, so there is no installer and no service to start. The README states you need Go installed to compile the code, and the module path in go.mod is github.com/luraproject/lura/v2. The go.mod file declares go 1.25.0 as the language version, so a toolchain at least that new is the safe assumption when building from source.

Add it to a project with:

```bash
go get github.com/luraproject/lura/v2
```

The README's ready-to-use example is the shortest path to a running process. It defines flags for the port, the log level, a debug switch and the configuration path, defaulting the config to /etc/lura/configuration.json.

```go
package main

import (
    "flag"
    "log"
    "os"

    "github.com/luraproject/lura/config"
    "github.com/luraproject/lura/logging"
    "github.com/luraproject/lura/proxy"
    "github.com/luraproject/lura/router/gin"
)

func main() {
    port := flag.Int("p", 0, "Port of the service")
    logLevel := flag.String("l", "ERROR", "Logging level")
    debug := flag.Bool("d", false, "Enable the debug")
    configFile := flag.String("c", "/etc/lura/configuration.json", "Path to the configuration filename")
    flag.Parse()

    parser := config.NewParser()
    serviceConfig, err := parser.Parse(*configFile)
    if err != nil {
        log.Fatal("ERROR:", err.Error())
    }
    serviceConfig.Debug = serviceConfig.Debug || *debug
    if *port != 0 {
        serviceConfig.Port = *port
    }

    logger, _ := logging.NewLogger(*logLevel, os.Stdout, "[LURA]")

    routerFactory := gin.DefaultFactory(proxy.DefaultFactory(logger), logger)

    routerFactory.New().Run(serviceConfig)
}
```

Running that binary with -c pointing at a configuration file should start an HTTP listener on the configured port and log through the logger created with the [LURA] prefix. The README does not include a sample configuration file, so the endpoints and backends have to come from docs/CONFIG.md. Expect the first run to fail with a parse error until that file exists and is valid; the example calls log.Fatal on a parse failure, which is the intended behaviour rather than a bug.

For contributors, the Makefile defines the working commands. make test runs go generate first, then go test -cover -race ./..., followed by the integration suites under test/, transport/ and proxy/ with the integration build tag. The generate target also builds four .so plugin examples with -buildmode=plugin, under transport/http/client/plugin/tests, transport/http/server/plugin/tests and two under proxy/plugin/tests. Those plugin builds are platform-sensitive, since Go plugins are not supported everywhere.

## Where Lura stops: no binary, and a licence you have to read

The clearest limitation is the one the README states itself. There is no gateway to install. If you want a running product, the README sends you to the KrakenD download page or the KrakenD CE repository. Choosing Lura means you are writing and maintaining the main function, the configuration file, the deployment and the upgrade path. That is a real cost, and for many teams it is the wrong trade.

The second limitation is the licence. The repository metadata reports NOASSERTION, which means no recognised SPDX identifier was detected, and the README only embeds a FOSSA status badge rather than naming the licence in prose. The LICENSE file is in the repository root, so the terms are readable, but nobody should plan a commercial deployment on the strength of a badge. Read LICENSE and, if the terms matter to your organisation, get them reviewed.

The third is the plugin path. The Makefile builds example plugins with -buildmode=plugin, which is a Go feature with known portability limits and version coupling between host and plugin. The README describes plugins as an extension mechanism, and the repository ships example plugins under transport and proxy, but it does not present them as a stable cross-platform distribution channel. Treat in-process plugins as a build-time concern tied to your Go version, not as a way to ship third-party code.

Finally, the README does not document rollback, version pinning policy or a migration guide between releases. Releases exist, with v2.13.0 published on 2025-10-30 and v2.12.0 and v2.12.1 on 2025-10-16, but the README is silent on what changes between them and how to move an existing gateway across. That silence is itself information: budget for reading release notes and the diff yourself.

## Lura compared with a packaged gateway such as Tyk or Kong

The honest comparison is not Lura against Kong or Tyk as products, because Lura is not one. It is the framework underneath KrakenD, and the README frames the choice plainly: this repository is for building from source or reusing components.

Packaged gateways such as Tyk OSS or Kong ship a binary or container, a configuration or admin API, and an operational surface that includes persistence, clustering and a plugin ecosystem with its own lifecycle. You adopt them and configure them. Lura gives you the aggregation proxy, the router adapters and the middleware interfaces, and you assemble the rest. The difference shows up the first time you need to change behaviour: with a packaged gateway you write against its extension points, with Lura you edit your own main package and rebuild.

KrakenD CE is the closest thing to a middle path, and the README points to it directly. It is built on this framework, so it offers the aggregation behaviour without asking you to write the wiring. If your requirement is a gateway with endpoint aggregation and you do not have a reason to own the binary, KrakenD CE is the more direct answer, and Lura is the answer when you do have that reason.

## Maintenance and upgrade cost

The repository is not archived, and the last push was on 2026-09-21, so the codebase is receiving changes. Releases are tagged, with v2.13.0 on 2025-10-30 and v2.12.0 and v2.12.1 both on 2025-10-16, which suggests patch releases land alongside feature releases rather than on a fixed schedule.

The upgrade cost is concentrated in your own code, not in a config file. Because you call the factories yourself, a signature change in config, proxy or router is a compile error in your main package rather than a runtime surprise, which is the better failure mode. The go.mod file pins a fairly wide dependency set, including gin, chi, gorilla/mux, httptreemux, negroni and the krakend/flatmap module, plus a long indirect list. Each of those is a surface you inherit. The Makefile's test target runs the unit suite with -race and the integration suites with the integration tag, which is the check to run before and after bumping the module version.

On licensing, the repository metadata reports NOASSERTION and the README names no licence in prose, only a FOSSA badge. Verify LICENSE before you depend on it. This is a description of what the repository states, not legal advice.

## Conclusion

Adopt Lura if you are a Go team that wants to own the gateway binary and compose your own middleware chain around the proxy and router factories. Do not adopt it if you want a downloadable gateway with a config file and an operations story out of the box; the README points that audience at the KrakenD binary instead. Before committing, verify the LICENSE file directly, since the repository metadata reports NOASSERTION rather than a recognised SPDX identifier, and check the docs/OVERVIEW.md component list to confirm the router and proxy factories you need are exposed.

## FAQ

### Is Lura an API gateway I can install and run?

No. The README describes Lura as a Go library for building proxies and API gateways, and states that if you need a fully functional gateway you should download the KrakenD binary or build KrakenD CE instead.

### Which Go version does Lura require?

The go.mod file declares go 1.25.0, and the README notes that Go must be installed on your system to compile the code.

### Which HTTP routers can I use with the Lura framework?

The go.mod file lists gin, chi, gorilla/mux, httptreemux and negroni, and the router directory contains the adapters. The README's example uses gin.DefaultFactory, so the router is chosen in your own main package.

## Sources

- [Issues](https://github.com/luraproject/lura/issues)
- [luraproject/lura on GitHub](https://github.com/luraproject/lura)
- [Project website](https://luraproject.org)
- [README](https://github.com/luraproject/lura/blob/master/README.md)
- [Releases](https://github.com/luraproject/lura/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/luraproject-lura
