# kataras/iris: a Go web framework with MVC and dependency injection built in

> Iris v12 is a BSD-3-Clause Go web framework whose README promises fast HTTP/2 serving plus MVC controllers and handler argument injection. Here is what the repository actually ships, how to get a first route running, and where the framework stops being the right choice.

**kataras/iris** — The fastest HTTP/2 Go Web Framework. New, modern and easy to learn. Fast development with Code you control. Unbeatable cost-performance ratio :rocket:

- Repository: https://github.com/kataras/iris
- Website: https://www.iris-go.com
- Stars: 25,562 · Forks: 2,426
- Language: Go
- License: BSD-3-Clause
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/kataras-iris

## What kataras/iris solves, and who it is aimed at

A Go team starting a web service usually assembles its own stack: a router, a JSON binder, a session store, a WebSocket library, a template renderer. Iris ships all of that in one module. The README describes it as "a fast, simple yet fully featured and very efficient web framework for Go", and the repository layout backs the claim up: the top level contains auth/, cache/, sessions/, websocket/, view/, i18n/, mvc/ and middleware/ as separate packages under the same module path.

The audience is Go developers who want convention over assembly. The mvc package lets you write a controller struct with methods that map to HTTP verbs and take typed arguments, and the framework fills those arguments from the request. The dependency-injection examples under _examples/dependency-injection go further, letting handlers declare typed input and output arguments instead of touching iris.Context directly. If that style appeals, Iris saves you a week of glue code. If you prefer explicit http.HandlerFunc signatures and a 300-line router, the same design will feel like a layer you did not ask for.

The project is not archived, and the last push to main was on 2026-07-27.

## How routing, MVC and dependency injection fit together

The entry point is iris.New(), which returns an Application. Routes register through methods such as app.Get and app.Handle, and middleware attaches with app.Use. The README's first example wires iris.Compression as middleware so responses are compressed, then registers a handler that writes HTML with ctx.HTML.

MVC sits on top of the same router. mvc.Configure takes a Party and a configuration function, and app.Handle(new(userController)) registers a controller. Method names map to HTTP verbs: the README's example names a method PutBy, which becomes a PUT route whose path parameter is the argument after "By". The framework reads the request body into the request struct and serialises the returned response struct, so the controller body contains no HTTP plumbing.

The dependency-injection path replaces the explicit context argument with declared parameters. A handler can ask for a value and return a value, and the framework resolves both sides. That is the mechanism behind the README's claim of "Code you control": the mapping is generated from your function signatures rather than from a config file.

One consequence worth stating plainly: because routing depends on method names and struct tags, a rename in your controller silently changes your public URL surface. There is no separate route table to review in a pull request.

## Installing kataras/iris and serving a first route

The module path is github.com/kataras/iris/v12 and go.mod declares go 1.26, so the toolchain needs to be at least that new. The README's minimal program creates an application, adds compression middleware, registers one GET route and listens on port 8080. Save this as main.go:

```go
package main

import "github.com/kataras/iris/v12"

func main() {
  app := iris.New()
  app.Use(iris.Compression)

  app.Get("/", func(ctx iris.Context) {
    ctx.HTML("Hello <strong>%s</strong>!", "World")
  })

  app.Listen(":8080")
}
```

Run it with go run main.go. A request to http://localhost:8080/ should return the rendered HTML string. Note that app.Listen takes an address with a colon and no host, which binds all interfaces on that port.

For a JSON API, the README shows a handler registered with a typed route macro, so the id parameter is validated as a UUID before your handler runs:

```go
app.Handle("PUT", "/users/{id:uuid}", updateUser)
```

Inside updateUser, ctx.Params().Get("id") returns the matched value, ctx.ReadJSON(&req) decodes the body, and ctx.StopWithError(iris.StatusBadRequest, err) aborts with a status when decoding fails. That is the whole loop for a first real endpoint.

The repository carries 285 examples under _examples, which is where to look next for routing, MVC and dependency injection patterns. The README points readers there rather than documenting every feature inline.

## The version story is the biggest practical risk

go.mod contains a retract directive covering v12.0.0 through v12.1.8, with the comment that older versions are retracted "as only latest is to be depended upon". Go's module system will refuse to select a retracted version unless something already requires it, so builds pinned to an early v12 tag can behave differently from a fresh resolution. The latest release listed for the v12 line is v12.2.11, published on 2024-04-24.

The README states that Iris v14 is in development and will arrive on a new import path. That is a deliberate compatibility choice: v12 keeps receiving fixes, and upgrading to v14 means changing the import line in every file that references the framework. The README also says v14 brings an application builder the compiler checks, request helpers that validate for you, a central error map, thirty built-in middleware and a book that ships inside the repository.

None of that is available in v12 today. If you adopt Iris now, you are adopting the v12 API with a known migration ahead of you. The README does not document a rollback procedure or a codemod for the import path change, so the migration cost is not quantified anywhere in the repository.

## Where Iris is the wrong tool

The dependency tree is the first constraint. go.mod requires a long list of third-party modules, including dgraph-io/badger, redis/go-redis, etcd bbolt, gopsutil, json-iterator, several template engines (jet, pongo2, jade, ace, raymond, blocks) and a markdown renderer. Importing the root package pulls in the framework's own code, but the module graph still carries these requirements, which matters for supply-chain review and for teams that vendor dependencies.

Second, the feature surface is opinionated. If you need a router and nothing else, Iris gives you a router plus MVC plus sessions plus WebSockets plus view engines, and you will spend time deciding which parts to ignore. A team that has standardised on net/http handlers and a separate template pipeline will find the MVC layer fights their existing conventions.

Third, the retraction policy is a maintenance signal. Retracting a range of published versions is legal in Go modules and the project explains why, but it means a lockfile referencing a retracted tag is a build you should re-resolve rather than trust.

Finally, the README's benchmark badge points at a separate repository, kataras/server-benchmarks, and the badge image is dated 2020. Treat the performance framing in the project description as a claim to verify on your own workload, not as a number you can rely on.

## How Iris differs from Gin and Echo

Gin and Echo occupy the same slot in the Go ecosystem: an HTTP router with middleware and context helpers. The difference is scope. Gin's centre of gravity is the routing tree and the context object; Echo adds a binder, a validator hook and a renderer interface, all fairly thin. Neither ships an MVC controller layer or handler argument injection as a first-class feature.

Iris includes both, plus a view package that wraps multiple template engines and a websocket package built on kataras/neffos rather than gorilla/websocket. That breadth is the actual differentiator. Choosing Iris over Gin is choosing to let the framework own more of your request pipeline, in exchange for writing less binding and mapping code.

The trade runs the other way too. Gin and Echo have smaller module graphs, which simplifies dependency auditing. If your team's review process treats every new transitive dependency as a cost, Iris asks you to pay that cost up front in return for the built-in pieces.

## Licence and upgrade cost

Iris is licensed under BSD-3-Clause, and the repository carries LICENSE and NOTICE files at the top level. BSD-3-Clause permits use in closed-source products provided the copyright notice and licence text are retained, and it includes a clause preventing the use of the copyright holder's name to endorse derived products. That is a permissive arrangement, but the NOTICE file is part of what you redistribute, so check that your build process carries it through. This is a description of the licence text, not legal advice; your own counsel should review redistribution if you ship binaries.

The upgrade cost is concrete. v12 is the current line and the README says it "keeps working and keeps getting fixes", while v14 lands on a new import path. Budget for a mechanical but repository-wide change to import statements when v14 stabilises. Because go.mod retracts v12.0.0 through v12.1.8, any project pinned below v12.1.9 should be re-resolved now rather than during the v14 migration.

## Conclusion

Adopt kataras/iris if you want a single Go dependency that covers routing, MVC controllers, sessions, WebSockets and view engines without assembling them yourself. Avoid it if you need a minimal router or cannot accept a framework that retracts its own older releases. Before writing production code, check which v12 version your build resolves, and read the v14 notes because the next major version arrives on a new import path.

## FAQ

### How do I install kataras/iris in a Go project?

The module path is github.com/kataras/iris/v12, and go.mod declares go 1.26, so your toolchain must be at least that version. The README's example imports github.com/kataras/iris/v12 and calls iris.New().

### Does kataras/iris support dependency injection in handlers?

Yes. The repository has an _examples/dependency-injection directory, and the README describes handlers with custom input and output arguments. The framework maps declared parameters and return values instead of requiring you to read from iris.Context.

### What happens to my code when Iris v14 is released?

The README states that v14 arrives on a new import path, so v12 keeps working and keeps getting fixes while the next major version uses a different import. Upgrading means changing the import line across your codebase.

### Why does go.mod retract several Iris v12 versions?

The retract directive covers v12.0.0 through v12.1.8, with a comment saying older versions are retracted because only the latest should be depended upon. Go will not select a retracted version unless an existing requirement forces it.

## Sources

- [kataras/iris on GitHub](https://github.com/kataras/iris)
- [License: BSD-3-Clause](https://github.com/kataras/iris/blob/main/LICENSE)
- [Project website](https://www.iris-go.com)
- [README](https://github.com/kataras/iris/blob/main/README.md)
- [Releases](https://github.com/kataras/iris/releases)

---

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