Special Packages and Directories in Go

Learn about internal, main, library, vendor and testdata quirks.


Special Packages

Main package

Every runnable program should contain a package named main and a function named main.

After your program gets compiled, and, when you want to run your program, this package’s main function will be called, and main function will orchestrate everything afterwards.

In some programs, as a convention, main func is also called as command or cmd.
This is the entry-point to your program.

Internal package

Naming your package as internal, hides your package’s internals even more, brings more encapsulation.

When you name a package as internal, it can only be imported from its parent directory’s packages. If you put into deeper sub-folders, one-step up, its parent packages can access it.

Internal package is used to make specific packages unimportable.

→ More about it here.


Library packages

This is not a special package name and it’s more like a convention. Sometimes (actually most of the times!) you just want to share the packages among your codebase or expose them as reusable code.

Without an entry-point, your code can only be used by other packages as a library.
Library packages are not runnable.

For example, many of the packages inside Go’s standard library are library packages and they’re not runnable programs. However, you can use them in a runnable program which has an entry point (remember main package’s main function?).


Special directories

These are not package names but only directory names. When you put code inside of them they will get interpreted by many go tools or programs differently.


Vendor directory

Starting with Go 1.5, when you name a directory as vendor, it allows you to put external package dependencies inside your application directory. Many Go tools don’t touch the stuff inside this directory.

For example, I’m using a vendor directory at the root of my project to save the external package dependencies.

A vendor directory from one of my latest projects.

This allows you to import an external package from vendor directory.

For example, when you type import "github.com/justinas/alice”, Go compiler searches the package inside the vendor directory. You don’t need to type as: import "vendor/github.com/justinas/alice", it automatically resolves to vendor directory. Many go dependency tools also use vendor folder.


And, there is also a directory named testdata etc. Testdata directories get skipped by go tools. You can store your testing samples here to use it in your code tests.


To learn more about packages, see my other tutorials.

I’m also creating an online course for Go → Join to my newsletter

“ Let’s stay in touch weekly for new tutorials and tips “


My twitter — @inancgumus — I mostly tweet about Go.