# Polylith in a Nutshell

Here we explain the basic concepts of Polylith.

## Function

Functions are the smallest building blocks in Polylith from which everything is created. Most communication within a Polylith system is done by using simple function calls as a way to connect the different high-level building blocks that a Polylith system consists of.

The simplicity of functions makes them fantastic building blocks for code:

1. *Encapsulation:* functions hide their implementation and only expose their signature.
2. *Simplicity:* functions have a single responsibility and don't mix nouns with verbs, which makes them fundamentally untangled.
3. *Stateless:* functions are just code; they don't contain state or instance.
4. *Purity:* functions can be [pure](https://en.wikipedia.org/wiki/Pure_function) (i.e. have no side-effects) which makes them easy to understand, reuse, test and parallelise.

These properties make functions (especially pure functions) inherently composable and testable units of code and a perfect foundation for a software architecture like Polylith.

## Library

<div align="left"><img src="https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAhrWK1psIWk5h5zNLV%2F-MLRFm_9NfJLsJpcXde8%2F-MLRaXuk9NequZe8_Cuz%2Flibrary-small.png?alt=media&#x26;token=7d801a59-0377-4cc7-bad7-1bea43015f90" alt=""></div>

A library is the kind of library we already know, a chunk of code that is compressed into a versioned file which can be downloaded from [Maven](https://mvnrepository.com/repos/central), [Clojars](https://clojars.org) or other repositories.

A library is a piece of code that lives in its own namespace which allows us to pick the libraries we want to use, without getting into name clashes (but sometimes [dependency hell](https://en.wikipedia.org/wiki/Dependency_hell)!).

We rely on tooling we already use, that hides the complexity of solving dependencies to other libraries and the caching of files on disk.&#x20;

## Component&#x20;

<div align="left"><img src="https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAhrWK1psIWk5h5zNLV%2F-MLRFm_9NfJLsJpcXde8%2F-MLR_67CCSuxxg6f-2Ir%2Fcomponent.png?alt=media&#x26;token=017e856d-67db-48cd-8852-bbf9d1549bb6" alt=""></div>

Components are high-level building blocks (bricks) which remove the need for layers (horizontal, vertical slice, or onion) in our architecture.&#x20;

A component can represent a part of our domain (e.g. cart, invoice, order, user, etc.), or be part of our infrastructure (e.g. authentication, database, log, etc.), or be an integration point to a third-party system, (e.g. crm-api, payment-api, sms-api, etc).

## Base

<div align="left"><img src="https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAhrWK1psIWk5h5zNLV%2F-MLRFm_9NfJLsJpcXde8%2F-MLRdJ4sVNRI3e5Gwai0%2Fbase.png?alt=media&#x26;token=decbf922-06c6-4f35-95a8-41ec7891f869" alt=""></div>

A base is a special type of building block (brick) that only exposes its functionality via a public API, e.g. REST, Lambda, GraphQL, gRPC, command-line, etc.

A base exposes a collection of endpoints via its API, and delegates the implementation of each endpoint to an appropriate component.

## Brick

![](https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LAhrWK1psIWk5h5zNLV%2Fuploads%2FRZMej4nrNznJMsZ6FGAW%2Fbrick.png?alt=media\&token=83f1a352-9d82-4781-906d-af299b642381)

Brick is the common name for a component or base, which are our building blocks (together with libraries).

## Project

<div align="left"><img src="https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAhrWK1psIWk5h5zNLV%2F-MLvr0aBnP0LO8jSq-lj%2F-MM-RiGnhRbPwxftgFvn%2Fproject.png?alt=media&#x26;token=74c5a034-92ed-49b8-81ec-7a1e26f7e60d" alt=""></div>

A project specifies which libraries and bricks should be included in an artifact, like a service, lambda function or command line tool. This allows for optimal code reuse of components across multiple projects.

## Development project

<div align="left"><img src="https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAhrWK1psIWk5h5zNLV%2F-MLvr0aBnP0LO8jSq-lj%2F-MM-Ro-4oXj9cBv5zswX%2Fdevelopment.png?alt=media&#x26;token=903d437b-781c-4aff-83c7-5a2767e13e4c" alt=""></div>

A development project is the place we use to work with all our libraries, components, and bases. It gives us a “monolithic development experience” with full code navigation, debugging, and refactoring across our entire codebase, and the possibility to work with our entire system in a single [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop).

## Workspace

<div align="left"><img src="https://3095132514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAhrWK1psIWk5h5zNLV%2F-MQN9oP-Om0Z1tpDg1FF%2F-MQNFuAC_AALiKTT02yQ%2Fworkspace.png?alt=media&#x26;token=019c1ca8-5422-429b-ae3f-40a767045122" alt=""></div>

A workspace is the place in a Polylith codebase where we store all our building blocks and configure our projects.

Now, let's dig deeper into the Polylith architecture to better understand how it solves these challenges.
