Module Basics
Modules are the foundation of code organization in Simplex. They help you group related functionality, control visibility, and create reusable components.
// Define a module with the 'module' keyword
module math {
// Public function - accessible from outside
pub fn add(a: i64, b: i64) -> i64 {
a + b
}
pub fn multiply(a: i64, b: i64) -> i64 {
a * b
}
// Private function - only accessible within this module
fn internal_helper(x: i64) -> i64 {
x * x
}
// Nested module
pub module advanced {
pub fn power(base: i64, exp: i64) -> i64 {
if exp == 0 { 1 }
else { base * power(base, exp - 1) }
}
}
}
Visibility Modifiers
Simplex provides fine-grained control over visibility with three levels:
module mylib {
// pub - Public: accessible from anywhere
pub struct PublicConfig {
pub name: String,
pub version: String,
}
// private (default) - Only accessible within this module
struct InternalState {
counter: i64,
cache: Map<String, Data>,
}
// pub(modulus) - Accessible within the same package only
pub(modulus) fn package_internal() -> String {
"This is only for other modules in this package"
}
pub struct User {
pub name: String, // Public field
pub(modulus) id: i64, // Package-internal field
password_hash: String, // Private field
}
}
Visibility Levels
pub = public everywhere, pub(modulus) = visible within package,
no modifier = private to module. Use the most restrictive visibility that works.
Import Syntax
Use the use keyword to import items from modules:
// Import a single item from a local module
use math::add
use math::advanced::power
// Import multiple items
use math::{add, multiply}
// Import all public items
use math::*
// Import with an alias
use math::multiply as mul
// Import from external packages (use modulus::)
use modulus::json::{parse, stringify}
use modulus::http::{Client, Request, Response}
use modulus::crypto::hash::sha256
fn main() {
let sum = add(5, 3)
let product = mul(4, 7)
let result = power(2, 10)
print("Sum: {sum}, Product: {product}, Power: {result}")
}
File-Based Modules
Each .sx file can be a module. The file name becomes the module name:
my_project/
sxpm.toml
src/
main.sx // Entry point
utils.sx // Module: utils
models/
mod.sx // Module: models (directory module)
user.sx // Module: models::user
product.sx // Module: models::product
// Re-export submodules
pub module user
pub module product
// Common types for the models module
pub trait Model {
fn id(&self) -> i64
fn validate(&self) -> Result<(), ValidationError>
}
use utils::format_date
use models::{Model, user::User, product::Product}
fn main() {
let user = User::new("Alice", "alice@example.com")
user.validate()?
print("User ID: {user.id()}")
}
Creating a Project with sxpm
The sxpm (Simplex Package Manager) tool helps you create and manage projects:
# Create a new binary project
$ sxpm new my_app
Created binary (application) `my_app` package
# Create a new library project
$ sxpm new my_lib --lib
Created library `my_lib` package
# Create with specific template
$ sxpm new web_api --template actix
Created binary (application) `web_api` package
$ cd my_app
$ tree
.
├── sxpm.toml
├── src
│ └── main.sx
└── tests
└── main_test.sx
Package Manifest (sxpm.toml)
The sxpm.toml file defines your package metadata and dependencies:
[package]
name = "my_app"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2024"
description = "A sample Simplex application"
license = "MIT"
repository = "https://github.com/username/my_app"
keywords = ["web", "api", "simplex"]
[dependencies]
http = "1.2.0"
json = "2.0.1"
crypto = { version = "1.0", features = ["aes", "rsa"] }
[dev-dependencies]
test_utils = "0.5.0"
mock_server = "1.1.0"
[build]
target = "native" # or "wasm", "llvm"
optimization = "release" # or "debug"
[features]
default = ["json"]
full = ["json", "xml", "yaml"]
experimental = []
Managing Dependencies
Add, remove, and update dependencies with sxpm:
# Add a dependency
$ sxpm add http
Adding http v1.2.0 to dependencies
# Add with specific version
$ sxpm add json@2.0.1
Adding json v2.0.1 to dependencies
# Add with features
$ sxpm add crypto --features aes,rsa
Adding crypto v1.0.0 to dependencies
# Add a dev dependency
$ sxpm add --dev test_utils
Adding test_utils v0.5.0 to dev-dependencies
# Add from git repository
$ sxpm add mylib --git https://github.com/user/mylib
Adding mylib (git) to dependencies
# Remove a dependency
$ sxpm remove json
Removing json from dependencies
# Update dependencies
$ sxpm update
Updating http v1.2.0 -> v1.3.0
Updating crypto v1.0.0 -> v1.0.2
# List dependencies
$ sxpm list
my_app v0.1.0
├── http v1.3.0
├── json v2.0.1
└── crypto v1.0.2
└── rand v0.8.0
Building and Testing
Build, run, and test your project with sxpm:
# Build the project
$ sxpm build
Compiling my_app v0.1.0
Finished dev [unoptimized + debuginfo] in 0.42s
# Build for release
$ sxpm build --release
Compiling my_app v0.1.0
Finished release [optimized] in 1.23s
# Run the project
$ sxpm run
Compiling my_app v0.1.0
Finished dev in 0.38s
Running `target/debug/my_app`
Hello, Simplex!
# Run with arguments
$ sxpm run -- --port 8080 --verbose
# Run tests
$ sxpm test
Compiling my_app v0.1.0
Finished test in 0.56s
Running tests/main_test.sx
running 4 tests
test test_add ... ok
test test_multiply ... ok
test test_async_fetch ... ok
test test_error_handling ... ok
test result: ok. 4 passed; 0 failed; 0 ignored
# Run specific tests
$ sxpm test test_add
$ sxpm test --filter "async"
# Check for errors without building
$ sxpm check
Checking my_app v0.1.0
Finished dev in 0.15s
use modulus::test::{assert, assert_eq, assert_err}
use my_app::{add, multiply, fetch_data}
#[test]
fn test_add() {
assert_eq(add(2, 3), 5)
assert_eq(add(-1, 1), 0)
}
#[test]
fn test_multiply() {
assert_eq(multiply(4, 5), 20)
}
#[test]
#[async]
fn test_async_fetch() {
let result = await fetch_data("test_id")
assert(result.is_ok())
}
#[test]
#[should_panic]
fn test_panic_case() {
divide(10, 0) // Should panic
}
Publishing Packages
Share your code with the Simplex community by publishing to the registry:
# Login to the registry
$ sxpm login
Enter API token: ********
Login successful for user@example.com
# Verify package before publishing
$ sxpm publish --dry-run
Packaging my_lib v0.1.0
Verifying my_lib v0.1.0
Compiling my_lib v0.1.0
Finished dev in 0.34s
Packaged 12 files, 45.2KB total
Ready to publish (dry run)
# Publish the package
$ sxpm publish
Packaging my_lib v0.1.0
Uploading my_lib v0.1.0
Published my_lib v0.1.0 to simplex-registry
# Yank a version (remove from registry)
$ sxpm yank my_lib@0.1.0
Yanking my_lib v0.1.0
# Search for packages
$ sxpm search json parser
json v2.0.1 - Fast JSON parsing and serialization
json-stream v1.0.0 - Streaming JSON parser
json-schema v0.8.0 - JSON Schema validation
Publishing Checklist
Before publishing: update version in sxpm.toml, write documentation,
add a LICENSE file, ensure all tests pass, and review your package with
sxpm publish --dry-run.
Standard Library Modules
Simplex comes with a comprehensive standard library. Here are the key modules:
// CLI - Command line argument parsing and terminal I/O
use modulus::cli::{Args, Command, prompt, style}
let args = Args::parse()
let name = prompt("Enter your name: ")
print(style("Success!").green().bold())
// HTTP - Client and server functionality
use modulus::http::{Client, Server, Request, Response, StatusCode}
let client = Client::new()
let response = await client.get("https://api.example.com/data")
// JSON - Parsing and serialization
use modulus::json::{parse, stringify, Value}
let data: Value = parse("{\"name\": \"Alice\"}")?
let json_str = stringify(&my_struct)
// File System - File and directory operations
use modulus::fs::{read_file, write_file, exists, create_dir}
let content = await read_file("config.toml")?
await write_file("output.txt", data)?
// Collections - Advanced data structures
use modulus::collections::{HashMap, HashSet, BTreeMap, VecDeque}
let cache: HashMap<String, Data> = HashMap::new()
// Crypto - Cryptographic functions
use modulus::crypto::{hash, encrypt, decrypt, random}
let hashed = hash::sha256(data)
let token = random::bytes(32)
// Time - Date and time handling
use modulus::time::{DateTime, Duration, Instant}
let now = DateTime::now()
let timeout = Duration::seconds(30)
// Regex - Regular expressions
use modulus::regex::{Regex, Match}
let pattern = Regex::new(r"\d{3}-\d{4}")?
let matches = pattern.find_all(text)
// Async - Async utilities
use modulus::async::{spawn, sleep, timeout, parallel, select}
// AI - Built-in AI capabilities
use modulus::ai::{Model, prompt, embed}
Try It Yourself
Create a reusable library package:
- Use
sxpm new myutils --libto create a library - Create modules for string utilities and math helpers
- Export public functions with proper visibility
- Write tests for all public functions
- Document your API with comments
- Try publishing with
sxpm publish --dry-run
Summary
In this tutorial, you learned:
- Defining modules with the
modulekeyword - Controlling visibility with
pub, private, andpub(modulus) - Importing items with
useand external packages withmodulus:: - Organizing code with file-based modules
- Creating projects with
sxpm new - Configuring packages with
sxpm.toml - Managing dependencies with
sxpm add/remove/update - Building and testing with
sxpm build/test - Publishing packages to the registry
- Using standard library modules
Congratulations!
You have completed all 10 Simplex tutorials! You now have a solid foundation in the language, from basic syntax to advanced features like actors, AI integration, async programming, and the module system. You are ready to build real-world applications with Simplex. Happy coding!