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 the main function will orchestrate everything afterwards.
In some programs, as a convention, main func is also called as command or cmd.


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 the 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.

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.

Alright, that’s all for now. Thank you for reading so far.
Let’s stay in touch:
- 📩 Join my newsletter
- 🐦 Follow me on twitter
- 📦 Get my Go repository for free tutorials, examples, and exercises
- 📺 Learn Go with my Go Bootcamp Course
- ❤️ Do you want to help? Please clap and share the article. Let other people also learn from this article.