Open-source project
free5gc/free5gc avatar
free5gc/free5gc

free5GC: a 3GPP R17 5G core network in Go, and how to get a first one running

Open source 5G core network based on 3GPP R17. What is free5GC The free5GC (a Linux Foundation project) is an open-source project for 5th generation (5G) mobile core networks.

2,360 stars756 forksGoApache-2.0

At a glance

What is it?
free5GC is a Linux Foundation project that implements the 5G core network as a set of Go network functions. It is aimed at labs, teaching and protocol work rather than at operators, and the install path runs through the repository's own setup script.
Who is it for?
free5GC suits university labs, protocol researchers and engineers who need to read or modify 5G core network function code, and it is a poor fit for anyone who wants a supported, appliance-like core with a vendor behind it. Before committing, verify that quick-setup.sh completes on your kernel and that the resulting configuration in config/ matches the release you pinned, because the repository tracks upstream 3GPP behaviour rather than a frozen product surface.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What free5GC actually is, and who it is built for

The README states the project plainly: free5GC is an open-source project for 5G mobile core networks, under the Linux Foundation, with the goal of implementing the 5G core network defined in 3GPP Release 15 and beyond. The repository description pins the current target at R17. It is written in Go, licensed Apache-2.0, and the code lives in the NFs/ directory as a set of separate network functions rather than one monolithic binary.

That last detail is the whole point. The Makefile lists the buildable functions explicitly: amf, ausf, bsf, nrf, nssf, pcf, smf, udm, udr, n3iwf, upf, chf, tngf, nef and scp, plus the webconsole. Each is its own program with its own configuration. If you want to understand how the AMF and SMF negotiate a PDU session, you can put a breakpoint in the AMF source and watch. You cannot do that with a closed core, and with most open alternatives you are reading a different language or a different decomposition.

The audience follows from that. This is for graduate students building a thesis testbed, for engineers implementing or debugging a 3GPP interface, and for vendors who need a reference core to point their gNB or UE at. It is not aimed at someone who wants to run a production subscriber base. The README points to the official forum for questions and keeps the issue list for bug reports and feature requests, which tells you the maintainers expect a technically literate user, not a support ticket.

How the network functions fit together in the repository

The architecture is the 3GPP service-based architecture, and the repository layout reflects it directly. NRF is the registration function that the others discover each other through. AMF terminates the control plane from the access network, SMF handles session management, UPF is the user plane, and AUSF, UDM and UDR sit behind authentication and subscriber data. NSSF, PCF, BSF, CHF, NEF, SCP, N3IWF and TNGF fill in the remaining roles.

The build system treats each function as a Go module under NFs/, and the version stamping in the Makefile is worth reading because it explains a real operational detail. VERSION comes from git describe --tags, and COMMIT_HASH comes from git submodule status for the relevant path. The network functions and the webconsole are git submodules, not directories committed into the top level. That is why .gitmodules exists at the root. If you clone without submodules, the NFs/ directory will be empty and make will produce nothing useful.

Configuration is not compiled in. The config/ directory at the top level holds the per-function configuration that the binaries read at startup, and cert/ holds certificates. This separation means you can retarget a function without rebuilding it, but it also means the running system is only as correct as the config directory you handed it. Two checkouts of the same release with different config/ contents are effectively two different networks.

Installing free5GC and running a first core

The repository does not inline installation steps in the README. It points to free5gc.org/guide/ for documentation, and the top level ships scripts that the guide is built around. The most direct path is quick-setup.sh, which is present at the repository root. Clone with submodules, because the network functions are submodules and a plain clone leaves NFs/ empty:

bash
git clone --recursive https://github.com/free5gc/free5gc.git
cd free5gc

With the tree populated, the setup script is the entry point the repository provides for preparing a host. It is at the root alongside reload_host_config.sh and force_kill.sh, which hints at what it does: it adjusts host networking, and the companion scripts reload that configuration or kill leftover processes.

bash
./quick-setup.sh

You can also build the functions yourself rather than relying on the script. The default Makefile goal is nfs, and the NF variable drives it, so a bare make builds the Go network functions. Adding the webconsole requires the all target, which also builds the webconsole frontend from its TypeScript sources.

bash
make
make all

Starting the core is the job of run.sh, which is also at the root. The repository also provides test.sh, test_ci.sh, test_ulcl.sh and test_multiUPF.sh, so the intended first-run experience is to execute the test scripts and watch them drive traffic through the functions rather than to bring up individual binaries by hand. For a container or cluster deployment, quick-setup-helm.sh and the ansible-helm/ directory are the Kubernetes path, and the repository also references Docker Compose workflows in its broader tooling. The README itself documents none of these commands; they are visible in the repository layout, and the guide at free5gc.org is where the project says the instructions live.

Where free5GC is the wrong tool

The most obvious failure mode is treating this as a product. There is no vendor, no support contract, and the README routes questions to a community forum. If your requirement is a core network with an escalation path when a call drops, free5GC is not that, and no amount of reading the source changes it.

A subtler limitation is the submodule structure. Because the network functions are separate repositories pinned by the parent, the top-level repository is closer to a manifest than to a single codebase. Version skew between the parent and a submodule is possible, and the Makefile's COMMIT_HASH logic exists precisely because the parent cannot know a submodule's state without asking. Anyone who vendors free5GC into their own build should decide early whether they pin submodule commits or track the parent, because mixing the two produces builds that are hard to reproduce.

There is also a scope boundary. The repository implements the core network. It does not give you a radio access network or a UE. The search interest around free5gc ueransim exists because you need something on the other side of the N1 and N2 interfaces before the core does anything visible. If you have no simulated or real gNB and no UE, a successfully started free5GC is a set of processes waiting for a connection, and that is the point at which many first attempts stall.

free5GC against Open5GS: same standard, different engineering

The comparison people reach for is free5GC versus Open5GS, and the difference is not feature lists, it is implementation language and the consequences that follow. free5GC is Go. Open5GS is C. That single choice propagates through everything a team cares about: how memory is managed, how concurrency is expressed, what a contributor needs to know before touching a network function, and how easy it is to add a new procedure.

For a research group, Go is usually the easier language to teach and to modify, and the one-function-per-module layout means a change to the SMF does not require understanding the AMF. For a team that needs to squeeze the user plane, C gives more direct control over memory layout and allocation, which matters in the UPF. Neither project is a drop-in for the other; the configuration formats, the internal interfaces and the deployment tooling all differ, so switching costs are real.

The honest framing is that both implement the same 3GPP specifications, and the choice is about which codebase your engineers can read, debug and extend. If your team writes Go, free5GC removes a language barrier that would otherwise dominate the first month. If your team writes C and cares about packet processing, that argument reverses.

Release cadence, upgrade cost and the Apache-2.0 terms

The repository is not archived, and its last push was on 2026-06-30, which is the same date as the v4.2.3 release. Before that, v4.2.2 landed on 2026-04-21 and v4.2.1 on 2026-03-04. That is a steady patch cadence across the first half of 2026, and the version numbers suggest the project is in a maintenance-and-fix phase on the 4.2 line rather than a rewrite.

Upgrade cost is dominated by the submodules and the config directory, not by the Go code. Because the network functions are pinned submodules, moving from one release to the next means moving several repositories in step, and the release notes are where the project documents what changed. If you have edited config/ or cert/, those edits are yours to reapply; nothing in the repository layout suggests a migration tool. Plan on diffing your configuration against the new release rather than overwriting it.

The licence is Apache-2.0, stated in the README and present as LICENSE at the root. There is also a THIRD-PARTY-NOTICES.txt, which is the file to read if you need to know what the network functions pull in. Apache-2.0 is permissive and includes an explicit patent grant, which is generally the reason projects in standards-adjacent spaces pick it. This is a description of the licence file, not legal advice; if you are shipping free5GC inside a product, the patent and notice obligations are worth a lawyer's ten minutes.

Editorial conclusion

free5GC suits university labs, protocol researchers and engineers who need to read or modify 5G core network function code, and it is a poor fit for anyone who wants a supported, appliance-like core with a vendor behind it. Before committing, verify that quick-setup.sh completes on your kernel and that the resulting configuration in config/ matches the release you pinned, because the repository tracks upstream 3GPP behaviour rather than a frozen product surface. The webconsole is a separate submodule, so check it is present in your checkout before assuming the graphical path exists.

Frequently asked questions

How do I install free5GC?

The README does not list install steps; it points to free5gc.org/guide/ for documentation. The repository root ships quick-setup.sh, and the network functions are git submodules, so clone with --recursive before running it.

What is free5GC?

It is a Linux Foundation open-source project implementing the 5G core network defined in 3GPP Release 15 and beyond, written in Go and licensed Apache-2.0. The repository description states the current target is R17.

Does free5GC run on Kubernetes?

The repository contains an ansible-helm/ directory and a quick-setup-helm.sh script at the root, which is the Helm and Kubernetes path. The README itself does not document these files, so the guide at free5gc.org is the place to check the supported procedure.

Which network functions does free5GC build by default?

The Makefile lists amf, ausf, bsf, nrf, nssf, pcf, smf, udm, udr, n3iwf, upf, chf, tngf, nef and scp, and the default goal is nfs. The webconsole is built only by the all target.

Why is the NFs directory empty after cloning free5GC?

The network functions are git submodules, which is why .gitmodules exists at the root. A clone without --recursive leaves the submodule directories unpopulated, and the Makefile reads commit information from those submodules.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/free5gc-free5gc.svg)](https://hysenlabs.com/projects/free5gc-free5gc)