Un programa en Ada se estructura como un conjunto de unidades de programa, pueden ser:
Las unidades de programa pueden anidarse unas dentro de otras, pero sólo los subprogramas, paquetes (especificación e implementación) y unidades genéricas pueden ocupar el nivel más externo de anidamiento y formar una unidad de compilación. Una unidad de compilación es un componente de un programa que puede compilarse por separado. Se distinguen dos clases de unidades de compilación: las subunidades, que se encuentran lógicamente incluidas en otro componente, y las unidades de librería, que son componentes independientes que pueden usarse en distintos programas.
Un subprograma principal inicia y gobierna la ejecución de un programa y desde él se desencadena la ejecución del resto de unidades que lo componen. Generalmente, el subprograma principal es un procedimiento sin parámetros. Implementaciones particulares del lenguaje pueden admitir otro tipo de subprogramas como subprograma principal.
Una unidad de compilación típica consta de dos partes: (1) una cláusula de contexto que sirve para especificar las unidades de librería que se necesitan (no hace falta si no se necesita ninguna) y (2) una unidad de programa (subprograma, paquete o unidad genérica).
El siguiente ejemplo muestra una unidad de compilación que proporciona un procedimiento sin parámetros llamado "Hola" que puede servir como subprograma principal de un programa o como unidad de librería utilizable como parte de un programa más complejo.
with Ada.Text_IO; use Ada.Text_IO; -- Cláusula de contexto
procedure Hola is -- Elemento de librería (subprograma)
begin
Put_Line("Hola mundo");
end Hola;