Watch the video (17 min)
On this page27 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. Why Organize and Document?
  5. 2. The Standard Package Layout
  6. 3. The Public Entry File
  7. 4. lib/src/ — The Storeroom
  8. 5. bin/, example/ and test/
  9. 6. README and CHANGELOG
  10. 7. Feature Folders vs Layer Folders
  11. 8. One Class per File?
  12. 9. Doc Comments: The First Sentence
  13. 10. [References] in Square Brackets
  14. 11. Code Samples in Doc Comments
  15. 12. Documenting Parameters in Prose
  16. 13. Generating HTML with dart doc
  17. 14. The public_member_api_docs Lint
  18. 15. A Real-World Example
  19. Code Examples
  20. Common Beginner Mistakes
  21. Best Practices
  22. Mini Challenge
  23. Practice Questions
  24. Practice Answers
  25. Quick Revision
  26. Key Takeaways
  27. What's Next?

Lecture 125 — Code Organization & Documentation

Category21 — Professional Dart Development
Lecture125 of 140
Estimated video length17 min
TargetDart 3.12.2
LevelAdvanced

Clean, immutable code is still hard to use if nobody can find it or tell what it does. A standard package layout shows where everything lives, and doc comments turn into a browsable website with dart doc.

Contents

Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways

Every message in this lecture is real. Each one was produced by running dart run, dart analyze, dart test and dart doc on the code shown, on Dart 3.12.2. Long folder paths in dart doc output are shortened to …/grade_book.


Prerequisites

Students should already understand, from Lectures 001–124:

  • /// doc comments (Lecture 003) and the Documentation guide of Effective Dart (Lecture 117)
  • export with show, and an entry file over a src/ folder (Lecture 102)
  • packages, package: imports and dart create -t package (Lectures 103, 113)
  • dart analyze, lint rules and analysis_options.yaml (Lectures 114, 117)
  • tests in test/ (Lectures 119–121)

Connection With Previous Lectures

Lectures 123 and 124 made our code clean and safe. But Ali's grade code is now one long file, and Sara wants to use it. Which names may she call? What does addMark(120) do? Today she must read every line to find out.


Learning Objectives

By the end of this lecture you will be able to:

  • Describe the standard folders of a Dart package: lib/, lib/src/, bin/, test/, example/
  • Expose a package's public surface from one entry file with export
  • Choose between feature folders and layer folders
  • Decide how many classes belong in one file
  • Write doc comments with a one-sentence summary, [references] and code samples
  • Document parameters in prose instead of tags
  • Generate an HTML documentation site with dart doc
  • Require docs on every public member with the public_member_api_docs lint

1. Why Organize and Document?

Organization answers where code lives; documentation answers what it does without opening it.

Analogy — a shop has a counter and a storeroom. Customers see the counter and the price labels; the storeroom is for staff. lib/ with its entry file is the counter, lib/src/ is the storeroom, and doc comments are the labels.


2. The Standard Package Layout

Lecture 113 showed the package template. Let's build a real package on it:

bash
dart create -t package grade_book
output
Creating grade_book using template package...

  .gitignore
  analysis_options.yaml
  CHANGELOG.md
  pubspec.yaml
  README.md
  example/grade_book_example.dart
  lib/grade_book.dart
  lib/src/grade_book_base.dart
  test/grade_book_test.dart

We will delete grade_book_base.dart and grow it into this:

output
grade_book/
├── bin/grade_book.dart              ← a program you can run
├── example/grade_book_example.dart  ← how to use the package
├── lib/
│   ├── grade_book.dart              ← the public entry file
│   └── src/                         ← the real code, private by convention
│       ├── grading.dart
│       ├── report_card.dart
│       └── student.dart
├── test/grade_book_test.dart
├── CHANGELOG.md
├── README.md
└── pubspec.yaml

Other projects import only package:grade_book/grade_book.dart.


3. The Public Entry File

lib/grade_book.dart holds no logic. It documents the library and exports the public surface — exactly the names users may call:

dart
/// Tools for recording student marks and printing report cards.
///
/// Create a [Student], add marks with [Student.addMark], then pass the
/// student to a [ReportCard] to print a summary.
library;

export 'src/grading.dart' show gradeFor;
export 'src/report_card.dart';
export 'src/student.dart';

show gradeFor keeps formatMark, a helper in the same file, out of the public surface (Lecture 102). library; gives the comment above it something to attach to.


4. lib/src/ — The Storeroom

Each src/ file holds one topic — lib/src/student.dart:

dart
/// A student and the marks they have earned.
class Student {
  /// Creates a student called [name] with no marks yet.
  Student(this.name);

  /// The student's name, such as `'Ali'`.
  final String name;

  final List<int> _marks = [];

  /// The marks added so far, in the order they were added.
  List<int> get marks => List.unmodifiable(_marks);

  /// The average of [marks], or `0` when there are none.
  double get average =>
      _marks.isEmpty ? 0 : _marks.reduce((a, b) => a + b) / _marks.length;

  /// Adds [mark] to this student's marks.
  ///
  /// The [mark] must be from 0 to 100; any other value throws an
  /// [ArgumentError] and leaves [marks] unchanged.
  void addMark(int mark) {
    if (mark < 0 || mark > 100) {
      throw ArgumentError.value(mark, 'mark', 'must be from 0 to 100');
    }
    _marks.add(mark);
  }
}

Files inside src/ import each other with relative paths — report_card.dart starts with import 'grading.dart';. Everything outside lib/ uses package: imports (Lecture 103).


5. bin/, example/ and test/

All three import only the entry file. example/grade_book_example.dart:

dart
import 'package:grade_book/grade_book.dart';

void main() {
  final ali = Student('Ali')
    ..addMark(80)
    ..addMark(75)
    ..addMark(85);
  print(ReportCard(ali).render());
}
output
Student: Ali
Average: 80.0
Grade: A

bin/grade_book.dart reads arguments (Lecture 113); dart run grade_book runs it:

dart
import 'package:grade_book/grade_book.dart';

void main(List<String> args) {
  final student = Student(args.first);
  for (final mark in args.skip(1)) {
    student.addMark(int.parse(mark));
  }
  print(ReportCard(student).render());
}
bash
dart run grade_book Sara 90 70 64
output
Student: Sara
Average: 74.7
Grade: B

test/grade_book_test.dart tests the same public surface, for example expect(gradeFor(79.9), 'B') (Lecture 120).


6. README and CHANGELOG

README.md says what the package does and shows a short usage sample. pub.dev uses it as the package's front page, and so does dart doc:

markdown
# grade_book

Record student marks and print report cards.

## Usage

```dart
final ali = Student('Ali')..addMark(80);
print(ReportCard(ali).render());
```

CHANGELOG.md lists what changed in each version from pubspec.yaml, newest first:

markdown
## 1.1.0

- Add `ReportCard`.

## 1.0.0

- Initial version.

7. Feature Folders vs Layer Folders

When src/ grows, group its files. Layer folders group by kind of code; feature folders group by what the code is about:

output
By layer                    By feature
lib/src/                    lib/src/
├── models/                 ├── students/
│   ├── student.dart        │   ├── student.dart
│   └── course.dart         │   └── student_report.dart
└── reports/                └── courses/
    ├── student_report.dart     ├── course.dart
    └── course_report.dart      └── course_report.dart

Layers suit small packages. As a package grows, prefer features: a change to students touches one folder.


8. One Class per File?

Dart does not require one class per file. Use these guidelines:

  • Give each important public class its own file, named after it in lowercase_with_underscores: ReportCard → report_card.dart.
  • Keep small helpers next to the class they serve.
  • Split a file when its parts change for different reasons.

9. Doc Comments: The First Sentence

Lecture 117 set the rules: ///, a one-sentence summary, names in brackets. The first sentence matters most, because tools show it alone in lists. Start with a verb for functions ("Returns…", "Adds…") and a noun phrase for classes and properties ("A student…", "The average…"). Put more detail in a new paragraph after a blank /// line:

dart
/// Adds [mark] to this student's marks.
///
/// The [mark] must be from 0 to 100; any other value throws an
/// [ArgumentError] and leaves [marks] unchanged.

10. [References] in Square Brackets

A name in brackets becomes a link in the generated docs. It can be a parameter ([mark]), a member ([marks]), another class ([ArgumentError]), or a member of another class ([Student.addMark]). Here is lib/src/report_card.dart:

dart
import 'grading.dart';
import 'student.dart';

/// A printable summary of one [Student]'s results.
class ReportCard {
  /// Creates a report card for [student].
  ReportCard(this.student);

  /// The student this card describes.
  final Student student;

  /// Returns the card as three lines: name, average and grade.
  ///
  /// The grade comes from [gradeFor].
  String render() =>
      'Student: ${student.name}\n'
      'Average: ${formatMark(student.average)}\n'
      'Grade: ${gradeFor(student.average)}';
}

11. Code Samples in Doc Comments

One example often explains more than a paragraph. Write it in a fenced block marked dart inside the comment — lib/src/grading.dart:

dart
/// Returns the letter grade for an [average] mark.
///
/// Averages of 80 and above get `'A'`, 65 and above `'B'`, 50 and above
/// `'C'`, and anything lower `'F'`.
///
/// ```dart
/// print(gradeFor(82.5)); // A
/// print(gradeFor(49.9)); // F
/// ```
String gradeFor(double average) {
  if (average >= 80) return 'A';
  if (average >= 65) return 'B';
  if (average >= 50) return 'C';
  return 'F';
}

/// Formats [mark] with one decimal place, such as `80.0`.
String formatMark(double mark) => mark.toStringAsFixed(1);

Short values go in single backticks: `'A'`.


12. Documenting Parameters in Prose

Some languages use tags like @param mark. Dart doesn't. Mention each parameter in a sentence, in brackets, together with its rules:

dart
/// Returns [price] with [percent] percent taken off.
///
/// The [percent] must be from 0 to 100. When [roundDown] is `true`, the
/// result is rounded down to whole rupees.
double discounted(double price, double percent, {bool roundDown = false}) {
  final result = price - price * percent / 100;
  return roundDown ? result.floorToDouble() : result;
}

void main() {
  print(discounted(2000, 15));
  print(discounted(1999, 15, roundDown: true));
}
output
1700.0
1699.0

Explain what the types cannot: ranges, units and bad input.


13. Generating HTML with dart doc

Run dart doc in the package folder:

bash
dart doc
output
Documenting grade_book...
Discovering libraries...
Linking elements...
Precaching local docs for 138012 elements...
Initialized dartdoc with 53 libraries
Generating docs for library grade_book.dart from package:grade_book/grade_book.dart...
Found 0 warnings and 0 errors.
Documented 1 public library in 3.6 seconds
Success! Docs generated into …/grade_book/doc/api

Open doc/api/index.html in a browser:

  • The front page shows README.md.
  • The library page shows the entry file's comment, then Classes (ReportCard, Student) and Functions (gradeFor), each with its first sentence only.
  • Class and member pages show full comments, code samples and implementations; every name in brackets is a link.
  • A search box sits at the top.

Only what the entry file exports is documented: formatMark has no page, and bin/, example/ and test/ are left out. doc/api is generated — add it to .gitignore. pub.dev runs the same tool for published packages.


14. The public_member_api_docs Lint

Forgetting a doc comment is easy. This lint, which is not in recommended, reports every public member in lib/ without one:

yaml
include: package:lints/recommended.yaml

linter:
  rules:
    - public_member_api_docs

Remove the comments above student and render() in report_card.dart:

output
   info - lib/src/report_card.dart:9:17 - Missing documentation for a public member. Try adding documentation for the member. - public_member_api_docs
   info - lib/src/report_card.dart:11:10 - Missing documentation for a public member. Try adding documentation for the member. - public_member_api_docs

2 issues found.

Private members such as _marks, and code in bin/ and test/, are not checked. Turn it on for packages others will use; for a small app it is usually too strict.


15. A Real-World Example

Before Ali shares a new version, he runs four commands from the package folder:

bash
dart format .
dart analyze
dart test
dart doc
output
Formatted 7 files (0 changed) in 0.01 seconds.
Analyzing grade_book...
No issues found!
00:00 +2: All tests passed!
...
Found 0 warnings and 0 errors.
Documented 1 public library in 3.6 seconds

Everything is clean. Sara reads the website, imports one file, and never opens lib/src/.


Code Examples

Example 1 — A One-Sentence Summary

dart
/// Returns the total of all [prices].
int total(List<int> prices) {
  var sum = 0;
  for (final price in prices) {
    sum += price;
  }
  return sum;
}

void main() {
  print(total([500, 50, 1500]));
}
output
2050

Example 2 — Documenting a Class and Its Members

dart
/// An item for sale in the shop.
class Product {
  /// Creates a product called [name] that costs [price] rupees.
  Product(this.name, this.price);

  /// The name printed on the receipt.
  final String name;

  /// The price in whole rupees.
  final int price;
}

void main() {
  final pen = Product('Pen', 50);
  print('${pen.name}: ${pen.price}');
}
output
Pen: 50

Example 3 — References Between Names

dart
/// The lowest mark that passes. Used by [isPassing].
const passMark = 50;

/// Whether [mark] is a passing mark.
///
/// A mark passes when it is at least [passMark].
bool isPassing(int mark) => mark >= passMark;

void main() {
  print(isPassing(65));
  print(isPassing(40));
}
output
true
false

Example 4 — A Code Sample in the Docs

dart
/// Returns [name] with its first letter in upper case.
///
/// ```dart
/// print(capitalize('sara')); // Sara
/// ```
String capitalize(String name) =>
    name.isEmpty ? name : '${name[0].toUpperCase()}${name.substring(1)}';

void main() {
  print(capitalize('sara'));
  print(capitalize('zayan'));
}
output
Sara
Zayan

Example 5 — A Library-Level Comment

dart
/// Helpers for printing shop receipts.
///
/// Use [rupees] to format every amount the same way.
library;

/// Formats [amount] as rupees with two decimal places.
String rupees(double amount) => 'Rs ${amount.toStringAsFixed(2)}';

void main() {
  print(rupees(1550));
}
output
Rs 1550.00

Example 6 — Student Marks

dart
/// Returns the average of [marks], or `0` when the list is empty.
double averageOf(List<int> marks) {
  if (marks.isEmpty) return 0;
  return marks.reduce((a, b) => a + b) / marks.length;
}

/// Returns `'Pass'` when [average] is at least 50, otherwise `'Fail'`.
///
/// Usually called with the result of [averageOf].
String resultFor(double average) => average >= 50 ? 'Pass' : 'Fail';

void main() {
  final marks = [80, 75, 85];
  final average = averageOf(marks);
  print('Ali: $average (${resultFor(average)})');
}
output
Ali: 80.0 (Pass)

Example 7 — Shopping Cart

dart
/// A shopping cart that adds up prices.
class Cart {
  final Map<String, int> _items = {};

  /// The sum of every item's price times its quantity.
  int get total {
    var sum = 0;
    _items.forEach((name, price) => sum += price);
    return sum;
  }

  /// Adds [quantity] of an item called [name] at [price] rupees each.
  ///
  /// Adding a name that is already in the cart replaces its line.
  void add(String name, int price, {int quantity = 1}) {
    _items[name] = price * quantity;
  }
}

void main() {
  final cart = Cart()
    ..add('Notebook', 500, quantity: 3)
    ..add('Pen', 50);
  print('Total: ${cart.total}');
}
output
Total: 1550

Example 8 — Bank Account

dart
/// A bank account that never goes below zero.
class Account {
  /// Creates an account for [owner] with an opening [balance].
  Account(this.owner, [this._balance = 0]);

  /// The name of the person who owns the account.
  final String owner;

  double _balance;

  /// The money in the account right now.
  double get balance => _balance;

  /// Removes [amount] from the [balance].
  ///
  /// Throws a [StateError] when [amount] is more than the [balance];
  /// the balance is then left unchanged.
  void withdraw(double amount) {
    if (amount > _balance) throw StateError('Not enough money');
    _balance -= amount;
  }
}

void main() {
  final account = Account('Sara', 1000)..withdraw(250.5);
  print('${account.owner}: ${account.balance}');
  try {
    account.withdraw(5000);
  } on StateError catch (e) {
    print(e.message);
  }
}
output
Sara: 749.5
Not enough money

Example 9 — Piggy Bank in lib/

This is the solution to the Mini Challenge below, so try that first. lib/piggy_bank.dart in a package named ex, with public_member_api_docs on:

dart
/// A piggy bank that counts the coins dropped into it.
class PiggyBank {
  /// Creates an empty piggy bank that belongs to [owner].
  PiggyBank(this.owner);

  /// The child who owns this piggy bank.
  final String owner;

  /// The number of rupees saved so far.
  int coins = 0;

  /// Adds [amount] rupees to [coins].
  void drop(int amount) {
    coins += amount;
  }
}

Example 10 — Temperature Package

A second package, weather_kit. lib/weather_kit.dart:

dart
/// Temperature tools for daily weather reports.
library;

export 'src/weather.dart' show dailyReport, toFahrenheit;

lib/src/weather.dart:

dart
/// Converts [celsius] to degrees Fahrenheit.
double toFahrenheit(double celsius) => celsius * 9 / 5 + 32;

/// Returns the highest of [readings] for [city] in °C and °F.
///
/// The [readings] are in Celsius and must not be empty.
String dailyReport(String city, List<double> readings) {
  final high = readings.reduce((a, b) => a > b ? a : b);
  return '$city: ${_oneDecimal(high)} °C / '
      '${_oneDecimal(toFahrenheit(high))} °F';
}

String _oneDecimal(double degrees) => degrees.toStringAsFixed(1);

bin/weather_kit.dart:

dart
import 'package:weather_kit/weather_kit.dart';

void main() {
  print(dailyReport('Lahore', [28, 33, 31]));
  print(toFahrenheit(25));
}
output
Lahore: 33.0 °C / 91.4 °F
77.0

Common Beginner Mistakes

1. Writing // instead of ///

dart
  // The student this card describes.
  final Student student;
output
   info - lib/src/report_card.dart:10:17 - Missing documentation for a public member. Try adding documentation for the member. - public_member_api_docs

A // comment is invisible to dart doc. Doc comments need three slashes.

2. Misspelling a reference

dart
/// A printable summary of one [Studnet]'s results.
output
  warning: unresolved doc reference [Studnet]
    from report_card.ReportCard: (file:///…/grade_book/lib/src/report_card.dart:5:7)
Found 1 warning and 0 errors.

dart doc still builds the site, but the link is dead. Read its warnings.

3. A library comment without library;

output
   info - lib/grade_book.dart:1:1 - Dangling library doc comment. Add a 'library' directive after the library comment. - dangling_library_doc_comments

A comment above export lines belongs to nothing. Put library; right under it.

4. Importing another package's src/ files

dart
import 'package:grade_book/src/grading.dart';

This compiles and formatMark works, but it is undocumented and may change in any version. Import only the entry file.

5. Comments that repeat the code

/// The name. above final String name; adds nothing. Say what the reader cannot see: /// The student's name, such as 'Ali'.


Best Practices

  • Use the standard layout and export a deliberate public surface with show or hide.
  • Prefer feature folders once src/ grows; name files after their main class.
  • Start every doc comment with a one-sentence summary; add detail in a new paragraph.
  • Document what is thrown, allowed ranges and units; add samples to anything non-obvious.
  • Keep README.md and CHANGELOG.md current; fix every dart doc warning.
  • Turn on public_member_api_docs for packages others use.

Mini Challenge

Zayan's package has this undocumented lib/piggy_bank.dart, and public_member_api_docs is on:

dart
class PiggyBank {
  PiggyBank(this.owner);

  final String owner;
  int coins = 0;

  void drop(int amount) {
    coins += amount;
  }
}
output
   info - lib/piggy_bank.dart:1:7 - Missing documentation for a public member. Try adding documentation for the member. - public_member_api_docs

…and four more lines like it, at 2:3, 4:16, 5:7 and 7:8.

Document it so dart analyze prints No issues found!.

Try it yourself before opening the solution.

Show solution

Use the documented class from Example 9. With it, this program in bin/piggy.dart:

dart
import 'package:ex/piggy_bank.dart';

void main() {
  final bank = PiggyBank('Zayan')
    ..drop(150)
    ..drop(50);
  print('${bank.owner}: ${bank.coins}');
}
output
Zayan: 200

Each of the five flagged names — class, constructor, owner, coins, drop — now has a one-sentence summary, so dart analyze reports No issues found!.


Practice Questions

Work through these in order — they run from beginner to application to challenge.

Beginner

  1. Which folder holds the package's entry file, and which holds code that is private by convention?
  2. Turn // Adds two numbers. above int add(int a, int b) => a + b; into a proper doc comment with references. Call add(80, 75).
  3. Which command generates HTML docs, where does it put them, and which file opens the site?

Application

  1. Write a one-sentence doc comment for double celsiusToFahrenheit(double celsius) and print celsiusToFahrenheit(30).

  2. A package ex has lib/src/cart.dart with cartTotal and lib/src/format.dart with formatPrice and roundPrice. Write lib/shop.dart so users get cartTotal and formatPrice, but not roundPrice.

  3. Sort these into feature folders: student.dart, fee.dart, student_report.dart, fee_receipt.dart.

  4. Rewrite this comment the Dart way:

    dart
    /// Records a mark.
    /// @param subject the subject
    /// @param mark the mark, 0-100
    void recordMark(String subject, int mark) {}
  5. Add a code sample to the doc comment of bool isPassing(int mark) => mark >= 50;.

Challenge

  1. With public_member_api_docs on, which lines of this lib/ file are flagged?

    dart
    /// A student's result in one exam.
    class ExamResult {
      ExamResult(this.subject, this.mark);
    
      final String subject;
      final int mark;
    
      /// Whether the result counts as a pass.
      bool get passed => _isValid() && mark >= 50;
    
      bool _isValid() => mark >= 0 && mark <= 100;
    }
  2. Plan a package bank_kit with an Account class, a formatMoney helper users may call and a roundCents helper they may not. Draw its folder tree and write its entry file.


Practice Answers

Question 1 — Solution

lib/ holds the entry file (lib/grade_book.dart); lib/src/ holds the private code.

Question 2 — Solution

dart
/// Returns the sum of [a] and [b].
int add(int a, int b) => a + b;

void main() {
  print(add(80, 75));
}
output
155

Question 3 — Solution

dart doc writes the site to doc/api; open doc/api/index.html.

Question 4 — Solution

dart
/// Converts [celsius] to degrees Fahrenheit.
double celsiusToFahrenheit(double celsius) => celsius * 9 / 5 + 32;

void main() {
  print(celsiusToFahrenheit(30));
}
output
86.0

Question 5 — Solution

dart
/// Tools for building shopping carts and printing prices.
library;

export 'src/cart.dart';
export 'src/format.dart' show formatPrice;

With print(formatPrice(cartTotal([500, 50, 1500]))); the output is:

output
Rs 2050

Calling roundPrice(2054) fails:

output
Error: Method not found: 'roundPrice'.

Question 6 — Solution

output
lib/src/
├── students/
│   ├── student.dart
│   └── student_report.dart
└── fees/
    ├── fee.dart
    └── fee_receipt.dart

Question 7 — Solution

dart
/// Records [mark] for the subject called [subject].
///
/// The [mark] must be from 0 to 100.
void recordMark(String subject, int mark) {
  print('$subject: $mark');
}

void main() {
  recordMark('Math', 80);
}
output
Math: 80

Question 8 — Solution

dart
/// Whether [mark] is at least 50.
///
/// ```dart
/// print(isPassing(65)); // true
/// print(isPassing(40)); // false
/// ```
bool isPassing(int mark) => mark >= 50;

void main() {
  print(isPassing(65));
  print(isPassing(40));
}
output
true
false

Question 9 — Solution

Three: the constructor (3:3), subject (5:16) and mark (6:13). The class and passed are documented, and _isValid is private.

Question 10 — Solution

output
bank_kit/
├── lib/
│   ├── bank_kit.dart
│   └── src/
│       ├── account.dart
│       └── money.dart      ← formatMoney and roundCents
├── test/bank_kit_test.dart
└── pubspec.yaml
dart
/// Bank accounts and money formatting.
library;

export 'src/account.dart';
export 'src/money.dart' show formatMoney;

Quick Revision

  1. What do lib/, lib/src/, bin/, example/ and test/ hold?
  2. When do feature folders beat layer folders?
  3. Why does the first sentence of a doc comment matter most?
  4. How do you document a parameter in Dart?
  5. What does dart doc leave out of the site?
  6. What does public_member_api_docs check, and where?

Key Takeaways

  • A package keeps its entry file in lib/, its code in lib/src/, and programs, examples and tests in bin/, example/ and test/.
  • The entry file exports the public surface; show and hide keep helpers private.
  • Prefer feature folders as code grows; give important classes their own file.
  • Doc comments: ///, a one-sentence summary, [references], code samples, and parameters described in prose.
  • README.md is the front page; CHANGELOG.md records each version.
  • dart doc builds a searchable site in doc/api from the exported names only.
  • public_member_api_docs flags every undocumented public member in lib/.

What's Next?

Lecture 126 — Performance & Memory. Our code is now organized and documented, but is it fast? Next we will measure how long code takes, see where memory goes, and learn which small choices make Dart programs quicker and lighter.


Video lecture

Subscribe
Placeholder video — the real recording isn't linked yet.