# How does the module system actually work?

**URL:** https://discourse.julialang.org/t/how-does-the-module-system-actually-work/53548
**Category:** New to Julia
**Tags:** question, package, first-steps
**Created:** [January 18, 2021, 4:55pm UTC](https://discourse.julialang.org/t/how-does-the-module-system-actually-work/53548 "2021-01-18T16:55:40Z")
**Posts on this page:** 1
**Showing post:** 3

<div class="post-metadata">

### Author: ![MA\_Laforge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ma_laforge/32/385_2.png) [@MA\_Laforge](https://discourse.julialang.org/u/MA_Laforge)
#### Post date: [January 18, 2021, 5:09pm UTC](https://discourse.julialang.org/t/how-does-the-module-system-actually-work/53548/3 "2021-01-18T17:09:50Z")

</div>

This strict dependency in declarations (that you see in C/C++) is not necessary in Julia. Having said that, I do find that simplifying your code to avoid circular dependencies is typically a good idea (whenever possible), as it makes your solution easier to read.

Going back to organizing your “module system”: In Julia, “software modules” are called “packages”, and I recently made a PR to help people get started:  
 → [FAQ: Creating your first package by ma-laforge · Pull Request #39186 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/39186)

But, to make it easier to read, here is a copy of it:

* * *

### Creating your first Julia package

A quick way to start any new package is to create a skeleton with the Julia package manager:

```julia-repl
julia> ]
pkg> generate path/to/my_package_repo/MyFirstPackage

```

The `path/to/my_package_repo` directory should now have the following contents:

```julia-auto
my_package_repo
└── MyFirstPackage
    ├── Project.toml
    └── src
        └── MyFirstPackage.jl

```

Using this method, a [UUID](@id man-code-loading-uuid) is automatically generated for the new package and written to `Project.toml`.

### Testing/developing your new package

An easy way to make packages available to the active Julia environment is to add a package repository to the `LOAD_PATH` variable:

```julia-repl
julia> push!(Base.LOAD_PATH, "/abs/path/to/my_package_repo")

```

To automate this process and make the repository available for every new julia session, add the above statement to `~/.julia/config/startup.jl`.

#### Hello World!

Since `pkg> generate` automatically creates a `greet()` function, you can call it after loading `MyFirstPackage` with either `import` or `using`:

```julia-repl
julia> import MyFirstPackage
julia> MyFirstPackage.greet()
Hello World!

```

### Alternative: Testing/developing your new package

It is also possible to add new packages-under-development to a given project/environment using [`pkg> dev /abs/path/to/my_package_repo/MyFirstPackage`](@ref Pkg). However, beginners might want to keep to the `LOAD_PATH` solution until Julia [projects & environments](@ref man-code-loading-environments) are well understood.

### Organizing package files

There are no strict rules on how to organize package source files, but the following is a good starting point:

```julia-auto
my_package_repo
└── MyFirstPackage
    ├── Project.toml
    └── src
        ├── MyFirstPackage.jl
        ├── component1.jl
        ├── component2.jl
        ├── component3
        │ ├── subcomponent1.jl
        │ └── subcomponent2.jl
        ├── component4.jl
        ...

```

In this example, a “component” could be anything that warrants being in a seperate file. For example:

- A set of functions to operate on a given type (like an “object” definition).
- Code used to display objects of multiple types (ex: collection of `show` methods).
- A collection of type definitions.
- A given software layer (ex: the external interface intended for users of the package).
- …

Here is a slightly more concrete example:

```julia-auto
my_package_repo
└── MyFirstPackage
    ├── Project.toml
    └── src
        ├── MyFirstPackage.jl
        ├── types.jl
        ├── mainalgorithm.jl
        ├── FileFormatA
        │ ├── FileFormatA.jl
        │ ├── reader.jl
        │ └── writer.jl
        ├── FileFormatB
        │ ├── FileFormatB.jl
        │ ├── reader.jl
        │ └── writer.jl
        └── display.jl

```

With such a file structure, `MyFirstPackage` is assembled by loading code from individual files (using `include()` statements). The following illustrates how this can be done:

`src/MyFirstPackage.jl`

```julia
module MyFirstPackage

#Import EXTERNAL packages required by solution:
using FFTW #Does frequency analysis
import Gtk #Needs a GUI (import avoids namespace pollution/collisions)
...

#Include INTERNAL project files themselves:
include("types.jl")
include("mainalgorithm.jl")
include("FileFormatA/FileFormatA.jl")
include("FileFormatB/FileFormatB.jl")
include("display.jl")

#Convenience functions:
readAdata(filename::String) = FileFormatA.readdata(filename)
readBdata(filename::String) = FileFormatB.readdata(filename)

...

end

```

`src/FileFormatA/FileFormatA.jl`

```julia
#Outside: Namespace is still "MyFirstPackage"

module FileFormatA #Preference: solution is cleaner with separate namespace
#Inside: Namespace is "MyFirstPackage.FileFormatA"

#Import EXTERNAL packages required by this "sub-module":
using DataFrames #Build on readily available reader/writer
...

#[Probably add type definitions here]

#Include INTERNAL project files themselves (file-relative):
include("reader.jl")
include("writer.jl")

...

end

```

On a conceptual basis, `src/FileFormatB/FileFormatB.jl` would be similar to `src/FileFormatA/FileFormatA.jl`.

---

_[View the full topic](https://discourse.julialang.org/t/how-does-the-module-system-actually-work/53548)._
