info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Registry architecture
GitLab has several registry applications. Given that they all leverage similar UI, UX, and business
logic, they are all built with the same architecture. In addition, a set of shared components
already exists to unify the user and developer experiences.
Existing registries:
- Package Registry
- Container Registry
- Infrastructure Registry
- Dependency Proxy
## Frontend architecture
### Component classification
All the registries follow an architecture pattern that includes four component types:
- Pages: represent an entire app, or for the registries using [vue-router](https://v3.router.vuejs.org/) they represent one router
route.
- Containers: represent a single piece of functionality. They contain complex logic and may
connect to the API.
- Presentationals: represent a portion of the UI. They receive all their data with `props` or through
`inject`, and do not connect to the API.
- Shared components: presentational components that accept a various array of configurations and are
shared across all of the registries.
### Communicating with the API
The complexity and communication with the API should be concentrated in the pages components, and
in the container components when needed. This makes it easier to:
- Handle concurrent requests, loading states, and user messages.
- Maintain the code, especially to estimate work. If it touches a page or functional component,
expect it to be more complex.
- Write fast and consistent unit tests.
### Best practices
- Use [`provide` or `inject`](https://v2.vuejs.org/v2/api/?redirect=true#provide-inject)
to pass static, non-reactive values coming from the app initialization.
- When passing data, prefer `props` over nested queries or Vuex bindings. Only pages and
container components should be aware of the state and API communication.
- Don't repeat yourself. If one registry receives functionality, the likelihood of the rest needing
it in the future is high. If something seems reusable and isn't bound to the state, create a
shared component.
- Try to express functionality and logic with dedicated components. It's much easier to deal with
events and properties than callbacks and asynchronous code (see