A Modula-2 egyik legsikeresebb jellemzője a modulok közötti interfészek explicit leírásának biztosítása. Az interfészek és modulok leírását gyakorlatilag egy az egyben örökölte a Modula-3 is.
A modulok a Modula-3 alapvető építőkövei. A modulok deklarációk nevesített gyűjteményei, beleértve a konstans-, típus-, változó-, és alprogram deklarációkat. Egy modul a saját deklarációit elérhetővé teheti más modulok - a kliensei - számára. Ezt a kívülről látható részt írják le az interfészek, amelyek mellett a moduloknak van rejtett implementációs része is.
Egy modul importálja azokat az interfészeket amelyeket felhasznál, és exportálja azokat, melyeket megvalósít. Az interfészek használatával biztonságosan tudjuk moduljainkat külön fordítani. Nem kell félni attól, hogy valamely hivatkozásunk érvénytelenné válik egy már lefordított modulban. Egy-egy modul kifelé csak az interfésze(i)n keresztül látszik, amely lehetőséget nyújt arra, hogy programunkat átlássuk anélkül, hogy a részleteket ismernénk. Ez a karbantartást, és a betanulást egyszerűsíti le nagy mértékben.
A főprogramnak (modulnak) exportálnia kell a Main interfészt. Egy implementációs részhez több interfész is tartozhat.
Az objektumokkal, mint nyelvi elemekkel, a 60-as évek közepén először a Simula nyelvben találkozhatunk. A Modula-3 objektumelvű jellemzői nagymértékben hasonlítanak a Simula hasonló jellemzőihez:
Az objektum típusok kombinálása a Modula-2 átlátszatlan típusaival egy merőben áj lehetőséget adnak a kezünkbe: a részlegesen átlátszatlan típus fogalmát. A részlegesen átlátszatlan típusban némely mező, illetve metódus látható kívülről, mások nem.
A generic modul igazából egy váz, melyet konkrét interfészekkel paraméterezve egy konkrét modult, illetve interfészt kaphatunk. Annak érdekében, hogy a nyelv egyszerűsége ne csorbuljon, a generic a Modula-3-ban csak modul szinten jelenik meg mint nyelvi elem. Nincs tehát generic típus, vagy eljárás. A generic paramétere is csak teljes interfész lehet. Természetesen ez valójában nem jelent megszorítást, hiszen szabadon írhatunk csak egy típust, vagy eljárást tartalmazó modult is, bár ez természetesen némi plusz munkával járhat. Cserébe viszont átláthatóbb struktúrájú kódot kapunk. Ugyancsak az egyszerűségre való törekvésnek köszönhető, hogy a genericekkel kapcsolatban nincs külön típusellenőrzés. Az implementációkra van bízva, hogy a generic példányosításánál típusellenőrzést végezzenek a paraméterekre vonatkozóan.
A Modula-2-ben a párhuzamosság biztosítása gyakorlatilag kimerült a korutinok támogatásával. Ennél a nyelv fejlesztői komolyabb támogatást akartak, így került a Modula-2+ nyelv párhuzamos eszköztára - mely a Mesa nyelv eszköztárára épül, némi egyszerűsítésekkel - különösebb változtatás nélkül a Modula-3 nyelvbe. Ez az eszköztár Hoare féle monitorokra épül.
Egy nyelvi jellemző nem biztonságos (unsafe) , ha annak nem megfelelő használata a futtató környezet nem megfelelő működéséhez vezethet, amikor is a program további futása nem a nyelv szemantikájának megfelelően folytatódik. Egy egyszerű példa erre, ha tömböt másolunk az indexhatárok ellenőrzése nélkül. Ennek ellentéte a biztonságos kód/jellemző, mely nem okoz ilyen galibákat, bárhogy is használjuk (természetesen a nyelv adta kereteken belül). Kívánatosnak látszik, hogy el tudjuk különíteni a programunk biztonságos és nem biztonságos szeleteit. Erre a Modula-3 nyelvi szinten ad lehetőséget. A nyelvben található néhány "unsafe" művelet. Ezeket csak olyan modulokban használhatunk, melyeket "unsafe"-nek jelölünk. Egy modul, ha "unsafe" modult használ, szintén "unsafe"-nek kell lennie. A fordító ezután minden olyan modulban, mely biztonságos (azaz nem "unsafe") megakadályoz minden olyan szituációt, mely a futtatókörnyezet összeomlásához vezethetne. "Unsafe" modulokban ez a programozóra van bízva.
Tipikus programozói hiba egy adatstruktúra felszabadítása ágy, hogy még van rá élő hivatkozás. Ekkor, ha el szeretnénk érni ezután a meglévő hivatkozáson keresztül az adatokat, futásidejű hibát kapunk (jó esetben), vagy akár az egész futtatórendszer is összeomolhat. Ugyanilyen probléma, ha nem szabadítjuk fel azokat a tárterületeket, amelyekre nincs több hivatkozás. Ezt memóriafolyásnak (memory leaking) nevezzük. Ekkor a programunk által foglalt memória folyamatosan nő, míg végül az összes rendelkezésre álló memóriát elfogyasztva erőforrás hiányában abortál. összevetve az előző fejezetben elmondottakkal, láthatjuk, hogy egy memóriaterület explicit felszabadítása tipikus "unsafe" művelet. Ennek elkerülésére vezették be a Modula-3-ban az őrzött (traced) referenciákat. Az ezek által fogalt memóriaterületet nem lehet explicit módon felszabadítani. Ehelyett a futtatókörnyezet ágynevezett szemétgyűjtő algoritmussal szabadítja fel automatikusan a már nem használt memóriaterületeket. Ezzel párhuzamosan lehetőség van őrizetlen (untraced) referenciák használatára is, melyeket a programozó szabadon kezelhet, a hozzájuk tartozó memóriaterületet explicit felszabadíthatja. Természetesen ennek használatára csak "unsafe" modulokban kerülhet sor.
A Modula-3 kivételkezelése követi a más nyelvekben megszokott szabályokat. A kivételek bárhol kiválthatók a programban, és a hívási láncban felfelé terjedve elkaphatók, illetve, ha nincs megfelelő kivételkezelő, akkor a futtatókörnyezetnek átadódva a program megállását okozzák.
A Modula-3 nyelv erősen típusos, mint az Algol családjába tartozó nyelvek általában. Az erős típusosság felvet néhány problémát, melyeket a különböző nyelveken más és más módon oldottak meg. Például:
A Modula-3 nyelv tervezésekor az egyik elsődleges szempont volt, hogy annyira egyszerű legyen a nyelv, amennyire csak a kifejezőerő és az átláthatóság csökkentése nélkül ez lehetséges. Ezért tudatosan arra törekedtek, hogy csak a legfontosabb, leghasználhatóbb jellemzők maradjanak a nyelvben, és minden más, amely különösebb fájdalom nélkül megoldható más, egyszerűbb, átláthatóbb eszközökkel is, elvetésre ítéltetett. A fő szempontok a következők voltak: