100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Your First D Program

Write, compile, and run your first D program, and understand the module, import, and main() concepts every D file relies on.

FoundationsBeginner8 min readJul 10, 2026
Analogies

Writing Your First D Program

The traditional first D program prints a greeting to the console, and even this tiny example demonstrates three core ideas that recur in every D program: importing a module from the standard library (Phobos), defining a main() function as the entry point, and calling a function using normal D syntax. Unlike scripting languages, D requires no boilerplate class wrapper around main() -- a bare function is enough, which keeps the very first program short and approachable.

🏏

Cricket analogy: Like a beginner's very first net session covering just three fundamentals, grip, stance, and a straight drive, before anything fancier, a first D program covers exactly three ideas: importing a module, defining main, and calling a function.

Anatomy of a Hello World Program

The complete program is import std.stdio; void main() { writeln("Hello, World!"); } -- import std.stdio brings in the standard I/O module, which defines writeln, a function that prints its arguments followed by a newline; void main() declares the entry point, returning nothing (void); and the body is a single statement calling writeln with a string literal. writeln is variadic and works with essentially any printable type without format specifiers, so writeln("Value: ", 42, ", pi: ", 3.14) concatenates and prints all its arguments in sequence, unlike C's printf, which requires matching format strings to argument types.

🏏

Cricket analogy: Like a commentator who can rattle off a batsman's name, score, and strike rate in one breath without needing separate scripted cue cards for each stat, writeln("Value: ", 42, ", pi: ", 3.14) prints mixed types in sequence without format specifiers.

d
import std.stdio;

void main() {
    writeln("Hello, World!");
}
d
import std.stdio;

void main() {
    int answer = 42;
    double pi = 3.14;
    writeln("Value: ", answer, ", pi: ", pi);
    // prints: Value: 42, pi: 3.14
}

Compiling and Running with dmd and rdmd

To compile the file traditionally, run dmd hello.d, which produces an executable (hello on Linux/macOS, hello.exe on Windows) that you then run separately with ./hello; dmd also accepts flags like -O for optimization, -release to strip runtime safety checks for a faster build, and -unittest to compile and run any unittest blocks in the file. For quick iteration, rdmd hello.d compiles and runs the program in a single command without leaving a persistent binary behind, which is why it's the preferred way to run small scripts and examples while learning.

🏏

Cricket analogy: Like the difference between a full first-class match that produces an official scorecard you keep (dmd producing a persistent binary) versus a quick throwdown session with no official record kept afterward (rdmd's disposable run), both let you play, but only one leaves lasting output.

bash
# Traditional compile-then-run
dmd hello.d
./hello                 # hello.exe on Windows

# One-step compile-and-run for quick iteration
rdmd hello.d

# Useful dmd flags
dmd -O -release hello.d   # optimized, safety checks stripped
dmd -unittest hello.d     # compiles and runs unittest blocks

Modules, Imports, and main()

Every .d file implicitly belongs to a module (named after the file by default, or explicitly via a module declaration at the top of the file), and import statements bring another module's public symbols into scope -- import std.stdio; imports the entire module, while import std.stdio : writeln, writefln; selectively imports just those two symbols, avoiding namespace clutter. The main() function can also be declared as int main() to return an explicit exit code, or int main(string[] args) to receive command-line arguments, mirroring C's argc/argv but as a safer, bounds-checked D array.

🏏

Cricket analogy: Like a cricket board that only allows one official captain per team at a time, naming two captains causes chaos, D allows only one main() function across an entire project, and dub will report a clear multiple main functions error if you break that rule.

A project can only have one main() function across all its modules -- if you get a "multiple main functions" linker error with dub, check that you haven't left a stray main() in more than one file. Also note that omitting import std.stdio; while calling writeln produces a clear "undefined identifier" compile error, not a runtime crash, so the mistake is caught immediately.

  • A minimal D program needs just an import, a main() function, and one function call -- no boilerplate class wrapper required.
  • import std.stdio brings in writeln, which prints any mix of argument types without format specifiers, unlike C's printf.
  • dmd hello.d compiles to a persistent executable; rdmd hello.d compiles and runs in one step without leaving a binary behind.
  • Useful dmd flags include -O (optimize), -release (strip runtime safety checks), and -unittest (compile and run unittest blocks).
  • Every .d file belongs to a module, named after the file by default or set explicitly with a module declaration.
  • import std.stdio : writeln, writefln; selectively imports only the listed symbols instead of the whole module.
  • A D project can have only one main() function; main can be void, return int for an exit code, or accept string[] args for command-line arguments.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#DProgrammingStudyNotes#YourFirstDProgram#Program#Writing#Anatomy#Hello#StudyNotes#SkillVeris#ExamPrep