Skip to content

Modules and Crates

TypeScript uses ESM import/export for code organisation and npm (or similar) for third-party packages. Rust has two parallel concepts: modules (mod/use) for organising code within a project, and crates (packages managed by Cargo) for third-party dependencies.

A module groups related items. Use pub to make items visible outside the module — the default is private.

// src/math.rs (a module file)
pub fn add(a: i32, b: i32) -> i32 { a + b }
fn helper() { } // private — not accessible outside
// src/main.rs
mod math; // declare the module (pulls in math.rs)
use math::add; // bring add into scope
fn main() {
println!("{}", add(1, 2));
}

Modules can also be declared inline with mod name { ... }.

A crate is Rust’s equivalent of an npm package. Cargo.toml is package.json. The workflow maps directly:

npmCargo
npm install serdecargo add serde
package.jsonCargo.toml
node_modules/~/.cargo/registry/ (shared cache)
import { x } from 'pkg'use pkg::x;
  • Items are private by default — only accessible in the same module and its descendants.
  • pub makes an item accessible from anywhere.
  • pub(crate) restricts visibility to the current crate only.
  • pub(super) restricts to the parent module.
TypeScript
// math.ts — named exports
export function add(a: number, b: number): number {
return a + b;
}
function helper() {} // not exported = module-private
// main.ts
import { add } from './math';
console.log(add(1, 2));
// package.json dependency
// "serde": "1.0" (hypothetical)
Rust
// src/math.rs
pub fn add(a: i32, b: i32) -> i32 { a + b }
fn helper() {} // private
// src/main.rs
mod math;
use math::add;
fn main() {
println!("{}", add(1, 2));
}
// Cargo.toml dependency
// [dependencies]
// serde = "1"

Playground note: multi-file module trees require cargo — run locally with cargo run.

What is the default visibility of a function in a Rust module?
What is the Rust equivalent of `npm install serde`?
What does `use std::collections::HashMap;` do in Rust?