Repository: zng-ui/zng (language: rust)

Issue:
Implement feature docs generation
We document features using `# comments`, do doc could collect these comments.

Maybe we could have an auto-generated README.md file for each crate (except zng).


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e3019b675..20f23e308 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 # Unpublished
 
+* Add Cargo feature documentation in each crate `README.md` and `lib.rs` docs.
 
 # 0.3.3
 
diff --git a/README.md b/README.md
index b739ca8a9..d75e45b0d 100644
--- a/README.md
+++ b/README.md
@@ -47,40 +47,129 @@ fn main() {
 
 See the [`API docs`] for more details.
 
+## Crates
+
+The `zng` crate is the only dependency you need to create apps, it re-exports the primary API of the other 
+crates in well organized and documented modules. 
+
+The other crates provide the full API that you might need to implement more advanced features, for example, a 
+custom property that modifies the behavior of an widget might need to reference the widget's internal state,
+this *internal* API will only be available in the widget's crate.
+
+<!--do doc --readme features-->
 ## Cargo Features
 
-Zng provides the following features which can be enabled in your `Cargo.toml` file:
-
-- **`view`** — Include the default view-process implementation.
-- **`view_prebuilt`** — Include the default view-process implementation as an embedded precompiled binary.
-- **`inspector`** — Instrument each property and widget instance with inspector nodes and extend windows to be inspected on Ctrl+Shift+I.
-- **`trace_widget`** — Instrument every widget outer-most node to trace UI methods.
-- **`trace_wgt_item`** — Instrument every property and intrinsic node to trace UI methods.
-- **`deadlock_detection`** — Spawns a thread on app creation that checks and prints `parking_lot` deadlocks.
-- **`http`** — Enables HTTP tasks, images download.
-- **`test_util`** — Test utilities.
-- **`multi_app`** — Allows multiple app instances per-process, one app per thread at a time. The `LocalContext` tracks
+This crate provides 25 feature flags, 3 enabled by default.
+
+#### `"view"`
+Include the default view-process implementation.
+
+#### `"view_prebuilt"`
+Include the default view-process implementation as an embedded precompiled binary.
+
+#### `"http"`
+Enables HTTP tasks and web features of widgets and services.
+
+#### `"debug_default"`
+Enable the `"dyn_*"`, `"inspector"` features in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_node"`
+Use more dynamic dispatch at the node level by enabling `UiNode::cfg_boxed` to box.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"inspector"`
+Instrument each property and widget instance with "Inspector" nodes and
+extend windows to be inspected on Ctrl+Shift+I.
+
+#### `"dyn_app_extension"`
+Use dynamic dispatch at the app-extension level.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"test_util"`
+Test utilities.
+
+#### `"multi_app"`
+Allows multiple app instances per-process.
+
+This feature allows multiple apps, one app per thread at a time. The `LocalContext` tracks
 what app is currently running in each thread and `app_local!` statics switch to the value of each app
 depending on the current thread.
-- **`hyphenation_embed_all`** — Embed hyphenation dictionaries for all supported languages. If enabled some 2.8MB of data is embedded, you can provide an alternative dictionary source using the `Hyphenation::dictionary_source` method.
-- **`dyn_node`** — Use more dynamic dispatch at the node level by enabling `UiNode::cfg_boxed` to box.
-- **`dyn_app_extension`** — Use dynamic dispatch at the app-extension level.
-- **`dyn_closure`** — Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
-- **`toml`** — Enable TOML configs.
-- **`ron`** — Enable RON configs.
-- **`yaml`** — Enable YAML configs.
-- **`material_icons`** — Include all *Material Icons* icon sets, each icon set embeds some 300KB of data.
-- **`material_icons_outlined`** Include *Material Icons Outlined* icon set. If enabled some icons of this set are used for some of the commands.
-- **`material_icons_filled`** Include *Material Icons Filled* icon set.
-- **`material_icons_rounded`** Include *Material Icons Rounded* icon set.
-- **`material_icons_sharp`** Include *Material Icons Sharp* icon set.
-- **`view_bundle_licenses`** Collects and bundles third-party licenses used by the `zng-view` crate.
-
-These features are enabled by default:
-
-- **`debug_default`** — Enable the `"dyn_*"` and `"inspector"` features for debug builds only.
-- **`ipc`** — Enables pre-build views and connecting to views running in another process.
-- **`view_software`** — Enables software renderer fallback in the default view-process (`"view"`).
+
+Not enabled by default, but enabled by `feature="test_util"`.
+
+#### `"trace_widget"`
+Instrument every widget outer-most node to trace UI methods.
+
+#### `"trace_wgt_item"`
+Instrument every property and intrinsic node to trace UI methods.
+
+Note that this can cause very large trace files and bad performance.
+
+#### `"deadlock_detection"`
+Spawns a thread on app creation that checks and prints `parking_lot` deadlocks.
+
+#### `"hyphenation_embed_all"`
+Embed hyphenation dictionaries for all supported languages.
+
+If enabled some 2.8MB of data is embedded, you can provide an alternative dictionary source using the
+`Hyphenation::dictionary_source` method.
+
+#### `"material_icons"`
+Include all Material Icons icon sets in the default app.
+
+#### `"material_icons_outlined"`
+Material Icons Outlined icon set.
+
+If enabled some icons of this set are used for some of the commands.
+
+#### `"material_icons_filled"`
+Material Icons Filled icon set.
+
+#### `"material_icons_rounded"`
+Material Icons Rounded icon set.
+
+#### `"material_icons_sharp"`
+Material Icons Sharp icon set.
+
+#### `"toml"`
+Enable TOML configs.
+
+#### `"ron"`
+Enable RON configs.
+
+#### `"yaml"`
+Enable YAML configs.
+
+#### `"view_software"`
+Enables software renderer fallback in the default view-process.
+
+If enabled and a native OpenGL 3.2 driver is not available the `swgl` software renderer is used.
+
+*Enabled by default.*
+
+#### `"view_bundle_licenses"`
+Collects and bundles third-party licenses used by the `zng-view` crate.
+
+Needs `cargo-about` and Internet connection during build.
+
+Not enabled by default. Note that `"view_prebuilt"` always bundles licenses.
+
+#### `"ipc"`
+Enables pre-build views and connecting to views running in another process.
+
+*Enabled by default.*
+
+<!--do doc --readme #SECTION-END-->
+
 
 ## Requirements
 
@@ -156,4 +245,4 @@ at your option.
 
 Unless you explicitly state otherwise, any contribution intentionally submitted
 for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
-dual licensed as above, without any additional terms or conditions.
\ No newline at end of file
+dual licensed as above, without any additional terms or conditions.
diff --git a/tools/do-tasks/src/main.rs b/tools/do-tasks/src/main.rs
index 3cca766e2..907ac94ad 100644
--- a/tools/do-tasks/src/main.rs
+++ b/tools/do-tasks/src/main.rs
@@ -1,3 +1,4 @@
+mod readme_gen;
 mod util;
 mod version_doc_sync;
 use std::format_args as f;
@@ -66,6 +67,7 @@ fn install(mut args: Vec<&str>) {
 
 // do doc [-o, --open] [<cargo-doc-args>]
 //        [-s, --serve]
+//        [--readme <crate>..]
 //
 //    Generate documentation for zng crates.
 //
@@ -78,7 +80,17 @@ fn install(mut args: Vec<&str>) {
 //
 //         Note: `basic-http-server` can be installed with cargo,
 //                it is not installed by `do install`.
+//     doc --readme
+//         Update READMEs tagged with `<!-- do doc --readme $tag -->` in all publish crates.
+//         Tags:
+//            header: Replaces the next paragraph with the shared header.
+//            features: Replaces or insert the next section with the `## Cargo Features`.
 fn doc(mut args: Vec<&str>) {
+    if take_flag(&mut args, &["--readme"]) {
+        readme_gen::generate(args);
+        return;
+    }
+
     let custom_open = if args.contains(&"--manifest-path") {
         if let Some(open) = args.iter_mut().find(|a| **a == "-o") {
             *open = "--open";
diff --git a/tools/do-tasks/src/readme_gen.rs b/tools/do-tasks/src/readme_gen.rs
new file mode 100644
index 000000000..076ed3431
--- /dev/null
+++ b/tools/do-tasks/src/readme_gen.rs
@@ -0,0 +1,179 @@
+use crate::{println, util};
+use std::{borrow::Cow, collections::HashSet, path::PathBuf};
+
+pub fn generate(args: Vec<&str>) {
+    for member in &util::publish_members() {
+        if !args.is_empty() && !args.contains(&member.name.as_str()) {
+            continue;
+        }
+
+        let readme = if member.name == "zng" {
+            PathBuf::from("zng/../README.md")
+        } else {
+            PathBuf::from(format!("{}/README.md", member.name))
+        };
+
+        println(&format!("{}/Cargo.toml", member.name));
+
+        let previous = if readme.exists() {
+            Cow::from(std::fs::read_to_string(&readme).unwrap())
+        } else {
+            Cow::from(README_TEMPLATE.to_owned())
+        };
+
+        let mut s = String::new();
+        let mut lines = previous.lines().peekable();
+        while let Some(line) = lines.next() {
+            use std::fmt::*;
+
+            writeln!(&mut s, "{line}").unwrap();
+            match line {
+                "<!--do doc --readme header-->" => {
+                    writeln!(&mut s, "{HEADER}").unwrap();
+                    while let Some(l) = lines.next() {
+                        if l.trim().is_empty() {
+                            break;
+                        }
+                    }
+                }
+                "<!--do doc --readme features-->" => {
+                    if let Some(l) = lines.peek() {
+                        if l.trim() == FEATURES_HEADER {
+                            while let Some(l) = lines.next() {
+                                if l == SECTION_END {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    let (features, defaults) = read_features(&format!("{}/Cargo.toml", member.name));
+                    if !features.is_empty() {
+                        writeln!(&mut s, "{FEATURES_HEADER}").unwrap();
+
+                        if features.len() == 1 {
+                            if defaults.contains(&features[0].name) {
+                                writeln!(&mut s, "\n This crate provides 1 feature flag, enabled by default.",).unwrap();
+                            } else {
+                                writeln!(&mut s, "\n This crate provides 1 feature flag, not enabled by default.",).unwrap();
+                            }
+                        } else {
+                            writeln!(
+                                &mut s,
+                                "\nThis crate provides {} feature flags, {} enabled by default.\n",
+                                features.len(),
+                                defaults.len(),
+                            )
+                            .unwrap();
+                        }
+
+                        for f in features {
+                            if f.docs.is_empty() {
+                                crate::error(format_args!("missing docs for `{}` feature", f.name));
+                            }
+                            writeln!(&mut s, "#### `\"{}\"`\n{}", f.name, f.docs).unwrap();
+                            if defaults.contains(&f.name) {
+                                writeln!(&mut s, "*Enabled by default.*\n").unwrap();
+                            }
+                        }
+
+                        writeln!(&mut s, "{SECTION_END}").unwrap();
+                    }
+                }
+                _ => {}
+            }
+        }
+
+        if s != previous {
+            std::fs::write(&readme, s.as_bytes()).unwrap();
+
+            if previous == README_TEMPLATE {
+                println("    generated");
+            } else {
+                println("    updated");
+            }
+        }
+    }
+}
+
+struct Feature {
+    name: String,
+    docs: String,
+}
+
+fn read_features(cargo: &str) -> (Vec<Feature>, HashSet<String>) {
+    let cargo = std::fs::read_to_string(cargo).unwrap();
+    let mut r = vec![];
+    let mut rd = HashSet::new();
+    let mut in_features = false;
+
+    let mut next_docs = String::new();
+
+    let rgx = regex::Regex::new(r#"(\w+)\s*=\s*\[.*"#).unwrap();
+
+    let mut lines = cargo.lines();
+    while let Some(line) = lines.next() {
+        let line = line.trim();
+        if line == "[features]" {
+            in_features = true;
+        } else if in_features {
+            use std::fmt::*;
+
+            if line.starts_with('[') && line.ends_with(']') {
+                break;
+            }
+
+            if line.starts_with('#') {
+                let docs = line.trim_start_matches(&['#', ' ']);
+                writeln!(&mut next_docs, "{docs}").unwrap();
+            } else {
+                if let Some(caps) = rgx.captures(&line) {
+                    let name = caps.get(1).unwrap().as_str();
+                    if name == "default" {
+                        let s = line.find('[').unwrap();
+                        let mut defaults = String::new();
+                        if let Some(e) = line.find(']') {
+                            defaults.push_str(&line[s + 1..e]);
+                        } else {
+                            defaults.push_str(&line[s + 1..]);
+                            while let Some(line) = lines.next() {
+                                if let Some(e) = line.find(']') {
+                                    defaults.push_str(&line[..e]);
+                                    break;
+                                }
+                                defaults.push_str(line);
+                            }
+                        }
+                        for dft in defaults.split(',') {
+                            rd.insert(dft.trim_matches(&['"', ' ']).to_owned());
+                        }
+                    } else {
+                        r.push(Feature {
+                            name: name.to_owned(),
+                            docs: std::mem::take(&mut next_docs),
+                        })
+                    };
+                } else {
+                    next_docs.clear();
+                }
+            }
+        }
+    }
+    (r, rd)
+}
+
+const HEADER: &str = "This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.\n";
+
+const README_TEMPLATE: &str = "\
+<!--do doc --readme header-->
+.
+
+
+<!--do doc --readme features-->
+
+
+";
+
+const FEATURES_HEADER: &str = "## Cargo Features";
+
+const SECTION_END: &str = "<!--do doc --readme #SECTION-END-->";
diff --git a/zng-app-context/Cargo.toml b/zng-app-context/Cargo.toml
index 12c051071..a0c7f1464 100644
--- a/zng-app-context/Cargo.toml
+++ b/zng-app-context/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.3.1"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_app_context"
 repository = "https://github.com/zng-ui/zng"
@@ -21,8 +21,12 @@ default = ["debug_default"]
 # depending on the current thread.
 multi_app = []
 
+# Enable `"multi_app"` in debug builds.
 debug_default = []
 
+# Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+#
+# This speeds-up compilation time at the cost of runtime.
 dyn_closure = []
 
 [dependencies]
diff --git a/zng-app-context/README.md b/zng-app-context/README.md
new file mode 100644
index 000000000..0729573c2
--- /dev/null
+++ b/zng-app-context/README.md
@@ -0,0 +1,29 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 3 feature flags, 1 enabled by default.
+
+#### `"multi_app"`
+Allows multiple app instances per-process.
+
+This feature allows multiple apps, one app per thread at a time. The `LocalContext` tracks
+what app is currently running in each thread and `app_local!` statics switch to the value of each app
+depending on the current thread.
+
+#### `"debug_default"`
+Enable `"multi_app"` in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-app-context/src/lib.rs b/zng-app-context/src/lib.rs
index f0ddf4045..8c55397df 100644
--- a/zng-app-context/src/lib.rs
+++ b/zng-app-context/src/lib.rs
@@ -1,9 +1,10 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
-//!
 //! App execution context.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-app-proc-macros/Cargo.toml b/zng-app-proc-macros/Cargo.toml
index 2639c37a7..846422fa9 100644
--- a/zng-app-proc-macros/Cargo.toml
+++ b/zng-app-proc-macros/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_app_proc_macros"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-app-proc-macros/README.md b/zng-app-proc-macros/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-app-proc-macros/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-app-proc-macros/src/lib.rs b/zng-app-proc-macros/src/lib.rs
index a0c6e9ab5..459548d2c 100644
--- a/zng-app-proc-macros/src/lib.rs
+++ b/zng-app-proc-macros/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
-//! [`zng`](../zng/index.html) proc-macros.
-
+//! Proc-macros for `zng-app`.
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-app/Cargo.toml b/zng-app/Cargo.toml
index b5c903607..538dbc768 100644
--- a/zng-app/Cargo.toml
+++ b/zng-app/Cargo.toml
@@ -15,12 +15,8 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 default = ["ipc", "debug_default"]
 
 # Enables pre-build views and connecting to views running in another process.
-# 
-# Enabled by default.
 ipc = ["zng-view-api/ipc"]
-# Enable the `"dyn_*""`, `"inspector"` features for debug builds only.
-#
-# Enabled by default.
+# Enable the `"dyn_*"` and `"inspector"` features in debug builds.
 debug_default = ["zng-var/debug_default", "zng-app-context/dyn_closure"]
 
 # Use dynamic dispatch at the node level by placing each property node in a `BoxedUiNode` and enabling `UiNode::cfg_boxed`.
@@ -41,15 +37,7 @@ dyn_app_extension = []
 # This speeds-up compilation time at the cost of runtime.
 dyn_closure = ["zng-var/dyn_closure", "zng-app-context/dyn_closure"]
 
-# like cfg(test) but also visible in docs and integration tests.
-#
-# USAGE:
-#
-# For zng-core maintainers, use `#[cfg(feature="test_util")]` in the helper types and places where
-# the types are used. Use `do` to run integration tests.
-#
-# For external dependents, build with this feature to use the test helper types that show
-# in the documentation.
+# Like `cfg(test)` but also visible in docs and integration tests.
 test_util = ["multi_app", "deadlock_detection"]
 
 # Allows multiple app instances per-process.
diff --git a/zng-app/README.md b/zng-app/README.md
index b734044de..2b36607da 100644
--- a/zng-app/README.md
+++ b/zng-app/README.md
@@ -1,2 +1,63 @@
-This crate is part of the [`zng`](https://github.com/zng-ui/zng) project.
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 11 feature flags, 2 enabled by default.
+
+#### `"ipc"`
+Enables pre-build views and connecting to views running in another process.
+
+*Enabled by default.*
+
+#### `"debug_default"`
+Enable the `"dyn_*"` and `"inspector"` features in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_node"`
+Use dynamic dispatch at the node level by placing each property node in a `BoxedUiNode` and enabling `UiNode::cfg_boxed`.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"inspector"`
+Instrument each widget instance to retain build information.
+
+#### `"dyn_app_extension"`
+Use dynamic dispatch at the app-extension level.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"test_util"`
+Like `cfg(test)` but also visible in docs and integration tests.
+
+#### `"multi_app"`
+Allows multiple app instances per-process.
+
+This feature allows multiple apps, one app per thread at a time. The `LocalContext` tracks
+what app is currently running in each thread and `app_local!` statics switch to the value of each app
+depending on the current thread.
+
+Not enabled by default, but enabled by `feature="test_util"`.
+
+#### `"trace_widget"`
+Instrument every widget outer-most node to trace UI methods.
+
+#### `"trace_wgt_item"`
+Instrument every property and intrinsic node to trace UI methods.
+
+Note that this can cause very large trace files and bad performance.
+
+#### `"deadlock_detection"`
+Spawns a thread on app creation that checks and prints `parking_lot` deadlocks.
+
+Not enabled by default, but enabled by `feature="test_util"`.
+
+<!--do doc --readme #SECTION-END-->
 
diff --git a/zng-app/src/lib.rs b/zng-app/src/lib.rs
index 7595509c3..0e066f54e 100644
--- a/zng-app/src/lib.rs
+++ b/zng-app/src/lib.rs
@@ -1,13 +1,15 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! App process implementation.
 //!
 //! # Widget Instantiation
 //!
 //! See [`enable_widget_macros!`] if you want to instantiate widgets without depending on the `zng` crate.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![recursion_limit = "256"]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
diff --git a/zng-clone-move/Cargo.toml b/zng-clone-move/Cargo.toml
index 087862f07..023e90b19 100644
--- a/zng-clone-move/Cargo.toml
+++ b/zng-clone-move/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.3"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_clone_move"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-clone-move/README.md b/zng-clone-move/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-clone-move/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-clone-move/src/lib.rs b/zng-clone-move/src/lib.rs
index 8846778a2..04dedf6a8 100644
--- a/zng-clone-move/src/lib.rs
+++ b/zng-clone-move/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Macros for declaring clone-move closures and async blocks.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-color-proc-macros/Cargo.toml b/zng-color-proc-macros/Cargo.toml
index bf61798d5..39fe46046 100644
--- a/zng-color-proc-macros/Cargo.toml
+++ b/zng-color-proc-macros/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_color_proc_macros"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-color-proc-macros/README.md b/zng-color-proc-macros/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-color-proc-macros/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-color-proc-macros/src/lib.rs b/zng-color-proc-macros/src/lib.rs
index f128b27b9..5f3752f29 100644
--- a/zng-color-proc-macros/src/lib.rs
+++ b/zng-color-proc-macros/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Proc-macros for `zng-color`.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-color/Cargo.toml b/zng-color/Cargo.toml
index 1fcf22c07..1a5cef093 100644
--- a/zng-color/Cargo.toml
+++ b/zng-color/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_color"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-color/README.md b/zng-color/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-color/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-color/src/lib.rs b/zng-color/src/lib.rs
index 1a5cd0021..de8458f42 100644
--- a/zng-color/src/lib.rs
+++ b/zng-color/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Color and gradient types, functions and macros, [`Rgba`], [`filter`], [`hex!`] and more.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 #![recursion_limit = "256"]
diff --git a/zng-ext-clipboard/Cargo.toml b/zng-ext-clipboard/Cargo.toml
index 360db87f9..8c70e4665 100644
--- a/zng-ext-clipboard/Cargo.toml
+++ b/zng-ext-clipboard/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_clipboard"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-ext-clipboard/README.md b/zng-ext-clipboard/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-ext-clipboard/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-ext-clipboard/src/lib.rs b/zng-ext-clipboard/src/lib.rs
index def93e313..59592d862 100644
--- a/zng-ext-clipboard/src/lib.rs
+++ b/zng-ext-clipboard/src/lib.rs
@@ -1,10 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Clipboard app extension, service and commands.
 //!
-
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-ext-config/Cargo.toml b/zng-ext-config/Cargo.toml
index 371742e7c..edf973960 100644
--- a/zng-ext-config/Cargo.toml
+++ b/zng-ext-config/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_config"
 repository = "https://github.com/zng-ui/zng"
@@ -12,8 +12,11 @@ categories = ["gui"]
 keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
+# Enable YAML support.
 yaml = ["dep:serde_yaml", "zng-ext-fs-watcher/yaml"]
+# Enable TOML support.
 toml = ["dep:toml", "zng-ext-fs-watcher/toml"]
+# Enable RON support.
 ron = ["dep:ron", "zng-ext-fs-watcher/ron"]
 
 [dependencies]
diff --git a/zng-ext-config/README.md b/zng-ext-config/README.md
new file mode 100644
index 000000000..5d6758cdc
--- /dev/null
+++ b/zng-ext-config/README.md
@@ -0,0 +1,21 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 3 feature flags, 0 enabled by default.
+
+#### `"yaml"`
+Enable YAML support.
+
+#### `"toml"`
+Enable TOML support.
+
+#### `"ron"`
+Enable RON support.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-ext-config/src/lib.rs b/zng-ext-config/src/lib.rs
index 86203de19..d7c58a75b 100644
--- a/zng-ext-config/src/lib.rs
+++ b/zng-ext-config/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Config service and sources.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
 #![warn(unused_extern_crates)]
diff --git a/zng-ext-font/Cargo.toml b/zng-ext-font/Cargo.toml
index e8ec10763..82a8b4bc0 100644
--- a/zng-ext-font/Cargo.toml
+++ b/zng-ext-font/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.3.3"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_font"
 repository = "https://github.com/zng-ui/zng"
@@ -12,7 +12,9 @@ categories = ["gui"]
 keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
-test_util = ["zng-app/test_util"]
+# Embed hyphenation dictionaries.
+#
+# See the `hyphenation` for more details.
 hyphenation_embed_all = ["hyphenation/embed_all"]
 
 [dependencies]
diff --git a/zng-ext-font/README.md b/zng-ext-font/README.md
new file mode 100644
index 000000000..50382487b
--- /dev/null
+++ b/zng-ext-font/README.md
@@ -0,0 +1,16 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+ This crate provides 1 feature flag, not enabled by default.
+#### `"hyphenation_embed_all"`
+Embed hyphenation dictionaries.
+
+See the `hyphenation` for more details.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-ext-font/src/lib.rs b/zng-ext-font/src/lib.rs
index 007d35818..247309700 100644
--- a/zng-ext-font/src/lib.rs
+++ b/zng-ext-font/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Font loading, text segmenting and shaping.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
 #![warn(unused_extern_crates)]
diff --git a/zng-ext-fs-watcher/Cargo.toml b/zng-ext-fs-watcher/Cargo.toml
index 95dc19f29..a79b9f03e 100644
--- a/zng-ext-fs-watcher/Cargo.toml
+++ b/zng-ext-fs-watcher/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_fs_watcher"
 repository = "https://github.com/zng-ui/zng"
@@ -12,9 +12,13 @@ categories = ["gui"]
 keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
+# Enable JSON helpers.
 json = ["dep:serde_json"]
+# Enable YAML helpers.
 yaml = ["dep:serde_yaml"]
+# Enable TOML helpers.
 toml = ["dep:toml"]
+# Enable RON helpers.
 ron = ["dep:ron"]
 
 [dependencies]
diff --git a/zng-ext-fs-watcher/README.md b/zng-ext-fs-watcher/README.md
new file mode 100644
index 000000000..ad14d1428
--- /dev/null
+++ b/zng-ext-fs-watcher/README.md
@@ -0,0 +1,24 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 4 feature flags, 0 enabled by default.
+
+#### `"json"`
+Enable JSON helpers.
+
+#### `"yaml"`
+Enable YAML helpers.
+
+#### `"toml"`
+Enable TOML helpers.
+
+#### `"ron"`
+Enable RON helpers.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-ext-fs-watcher/src/lib.rs b/zng-ext-fs-watcher/src/lib.rs
index 7eb44ef9e..e005f360c 100644
--- a/zng-ext-fs-watcher/src/lib.rs
+++ b/zng-ext-fs-watcher/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! File system events and service.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
 #![warn(unused_extern_crates)]
diff --git a/zng-ext-image/Cargo.toml b/zng-ext-image/Cargo.toml
index 13360cace..f1261f36a 100644
--- a/zng-ext-image/Cargo.toml
+++ b/zng-ext-image/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_image"
 repository = "https://github.com/zng-ui/zng"
@@ -12,6 +12,7 @@ categories = ["gui"]
 keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
+# Enable web image source.
 http = ["zng-task/http"]
 
 [dependencies]
diff --git a/zng-ext-image/README.md b/zng-ext-image/README.md
new file mode 100644
index 000000000..082485b65
--- /dev/null
+++ b/zng-ext-image/README.md
@@ -0,0 +1,14 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+ This crate provides 1 feature flag, not enabled by default.
+#### `"http"`
+Enable web image source.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-ext-image/src/lib.rs b/zng-ext-image/src/lib.rs
index 8782113d0..560ebabfd 100644
--- a/zng-ext-image/src/lib.rs
+++ b/zng-ext-image/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Image loading and cache.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-ext-input/Cargo.toml b/zng-ext-input/Cargo.toml
index e43bde08f..2a5c82e95 100644
--- a/zng-ext-input/Cargo.toml
+++ b/zng-ext-input/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.3.3"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_input"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-ext-input/README.md b/zng-ext-input/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-ext-input/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-ext-input/src/lib.rs b/zng-ext-input/src/lib.rs
index c759eb885..1cafba37c 100644
--- a/zng-ext-input/src/lib.rs
+++ b/zng-ext-input/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Input events and focused widget.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-ext-l10n-proc-macros/Cargo.toml b/zng-ext-l10n-proc-macros/Cargo.toml
index 9f6c5676e..50505fcd7 100644
--- a/zng-ext-l10n-proc-macros/Cargo.toml
+++ b/zng-ext-l10n-proc-macros/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_l10n_proc_macros"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-ext-l10n-proc-macros/README.md b/zng-ext-l10n-proc-macros/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-ext-l10n-proc-macros/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-ext-l10n-proc-macros/src/lib.rs b/zng-ext-l10n-proc-macros/src/lib.rs
index ccefb51b3..605194965 100644
--- a/zng-ext-l10n-proc-macros/src/lib.rs
+++ b/zng-ext-l10n-proc-macros/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Proc-macros for `zng-ext-l10n`.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-ext-l10n/Cargo.toml b/zng-ext-l10n/Cargo.toml
index fb8dd3a2a..3ba09d1d6 100644
--- a/zng-ext-l10n/Cargo.toml
+++ b/zng-ext-l10n/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.3.3"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_l10n"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-ext-l10n/README.md b/zng-ext-l10n/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-ext-l10n/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-ext-l10n/src/lib.rs b/zng-ext-l10n/src/lib.rs
index 6beae7705..caabbeb3a 100644
--- a/zng-ext-l10n/src/lib.rs
+++ b/zng-ext-l10n/src/lib.rs
@@ -1,10 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Localization service, [`l10n!`] and helpers.
 //!
-
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-ext-undo/Cargo.toml b/zng-ext-undo/Cargo.toml
index 6d39d611b..e5b5c894b 100644
--- a/zng-ext-undo/Cargo.toml
+++ b/zng-ext-undo/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_undo"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-ext-undo/README.md b/zng-ext-undo/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-ext-undo/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-ext-undo/src/lib.rs b/zng-ext-undo/src/lib.rs
index a7b77cb4d..1f6ce0750 100644
--- a/zng-ext-undo/src/lib.rs
+++ b/zng-ext-undo/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Undo-redo app extension, service and commands.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 #![recursion_limit = "256"]
diff --git a/zng-ext-window/Cargo.toml b/zng-ext-window/Cargo.toml
index 5fddaf774..902be15a3 100644
--- a/zng-ext-window/Cargo.toml
+++ b/zng-ext-window/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_ext_window"
 repository = "https://github.com/zng-ui/zng"
@@ -12,6 +12,7 @@ categories = ["gui"]
 keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
+# Enable test util methods, `doc_test_window`.
 test_util = []
 
 [dependencies]
diff --git a/zng-ext-window/README.md b/zng-ext-window/README.md
new file mode 100644
index 000000000..411680ab7
--- /dev/null
+++ b/zng-ext-window/README.md
@@ -0,0 +1,14 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+ This crate provides 1 feature flag, not enabled by default.
+#### `"test_util"`
+Enable test util methods, `doc_test_window`.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-ext-window/src/lib.rs b/zng-ext-window/src/lib.rs
index 860e00230..e2e377842 100644
--- a/zng-ext-window/src/lib.rs
+++ b/zng-ext-window/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! App window and monitors manager.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 // suppress nag about very simple boxed closure signatures.
diff --git a/zng-handle/Cargo.toml b/zng-handle/Cargo.toml
index dc4fbdf28..690e27015 100644
--- a/zng-handle/Cargo.toml
+++ b/zng-handle/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.3"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_handle"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-handle/README.md b/zng-handle/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-handle/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-handle/src/lib.rs b/zng-handle/src/lib.rs
index a818ede46..29da56ed8 100644
--- a/zng-handle/src/lib.rs
+++ b/zng-handle/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Resource handle type.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-l10n-scraper/README.md b/zng-l10n-scraper/README.md
index 464f88110..7c2e21855 100644
--- a/zng-l10n-scraper/README.md
+++ b/zng-l10n-scraper/README.md
@@ -1,4 +1,5 @@
-This crate is part of the [`zng`](https://github.com/zng-ui/zng) project.
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
 
 Command-line tool that scraps l10n text from Zng apps code. See [documentation] for more details.
 
@@ -29,4 +30,6 @@ Options:
 
 ```
 
-[documentation]: https://zng-ui.github.io/doc/zng/l10n/macro.l10n.html#scrap-template
\ No newline at end of file
+[documentation]: https://zng-ui.github.io/doc/zng/l10n/macro.l10n.html#scrap-template
+
+<!--do doc --readme features-->
diff --git a/zng-layout/Cargo.toml b/zng-layout/Cargo.toml
index dc1472488..2da0975ca 100644
--- a/zng-layout/Cargo.toml
+++ b/zng-layout/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.5"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_layout"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-layout/README.md b/zng-layout/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-layout/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-layout/src/lib.rs b/zng-layout/src/lib.rs
index 60c3f237a..59013010c 100644
--- a/zng-layout/src/lib.rs
+++ b/zng-layout/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Contextual layout units.
 //!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-state-map/Cargo.toml b/zng-state-map/Cargo.toml
index 45c377719..78c530b24 100644
--- a/zng-state-map/Cargo.toml
+++ b/zng-state-map/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_state_map"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-state-map/README.md b/zng-state-map/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-state-map/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-state-map/src/lib.rs b/zng-state-map/src/lib.rs
index 4665ccd97..d43f3b5f9 100644
--- a/zng-state-map/src/lib.rs
+++ b/zng-state-map/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Hash-map of type erased values, useful for storing assorted dynamic state.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-task-proc-macros/Cargo.toml b/zng-task-proc-macros/Cargo.toml
index 86ce63649..f58898a87 100644
--- a/zng-task-proc-macros/Cargo.toml
+++ b/zng-task-proc-macros/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_task_proc_macros"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-task-proc-macros/README.md b/zng-task-proc-macros/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-task-proc-macros/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-task-proc-macros/src/lib.rs b/zng-task-proc-macros/src/lib.rs
index 0ec7b0fef..49867f4f0 100644
--- a/zng-task-proc-macros/src/lib.rs
+++ b/zng-task-proc-macros/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Proc-macros for `zng-task`.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-task/Cargo.toml b/zng-task/Cargo.toml
index 5f9efcce1..9e943af39 100644
--- a/zng-task/Cargo.toml
+++ b/zng-task/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.5"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_task"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-task/README.md b/zng-task/README.md
new file mode 100644
index 000000000..2e3b7abd2
--- /dev/null
+++ b/zng-task/README.md
@@ -0,0 +1,21 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 3 feature flags, 0 enabled by default.
+
+#### `"deadlock_detection"`
+Enables parking_lot deadlock detection.
+
+#### `"http"`
+Enables http tasks.
+
+#### `"test_util"`
+Enabled by doc tests.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-task/src/lib.rs b/zng-task/src/lib.rs
index 5a2e058e8..c603c38a4 100644
--- a/zng-task/src/lib.rs
+++ b/zng-task/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Parallel async tasks and async task runners.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-time/Cargo.toml b/zng-time/Cargo.toml
index 8f704cffc..b6001223f 100644
--- a/zng-time/Cargo.toml
+++ b/zng-time/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_time"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-time/README.md b/zng-time/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-time/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-time/src/lib.rs b/zng-time/src/lib.rs
index b2fe7b7c7..437788450 100644
--- a/zng-time/src/lib.rs
+++ b/zng-time/src/lib.rs
@@ -1,7 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
+//!
 //! Configurable instant type and service.
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 
 use std::{
     fmt, ops,
diff --git a/zng-tp-licenses/Cargo.toml b/zng-tp-licenses/Cargo.toml
index eb6685c93..50fe65185 100644
--- a/zng-tp-licenses/Cargo.toml
+++ b/zng-tp-licenses/Cargo.toml
@@ -3,7 +3,7 @@ name = "zng-tp-licenses"
 version = "0.2.3"
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_third_party_licenses"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-tp-licenses/README.md b/zng-tp-licenses/README.md
new file mode 100644
index 000000000..f4662bdad
--- /dev/null
+++ b/zng-tp-licenses/README.md
@@ -0,0 +1,18 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 0 enabled by default.
+
+#### `"build"`
+Include helpers for collecting third-party licenses.
+
+#### `"bundle"`
+Include helpers for deserializing `build` encoded licenses.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-tp-licenses/src/lib.rs b/zng-tp-licenses/src/lib.rs
index 2c1dc3fec..53551f45a 100644
--- a/zng-tp-licenses/src/lib.rs
+++ b/zng-tp-licenses/src/lib.rs
@@ -1,13 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
-//! Third party license management and collection.
 //!
-//! Some licenses require that they must be accessible in the final binary, usually in an "about" screen. This
-//! crate defines the data type for this about screen and optionally uses `cargo about` to find and bundle all
-//! license files.
+//! Third party license management and collection.
 //!
+//! # Crate
 //!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 
 use std::fmt;
 
diff --git a/zng-txt/Cargo.toml b/zng-txt/Cargo.toml
index a390fa9b5..1c657218b 100644
--- a/zng-txt/Cargo.toml
+++ b/zng-txt/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_txt"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-txt/README.md b/zng-txt/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-txt/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-txt/src/lib.rs b/zng-txt/src/lib.rs
index 9a08d4e66..56b9740d8 100644
--- a/zng-txt/src/lib.rs
+++ b/zng-txt/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! String type optimized for sharing.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-unique-id/Cargo.toml b/zng-unique-id/Cargo.toml
index 895ad9524..dc2112619 100644
--- a/zng-unique-id/Cargo.toml
+++ b/zng-unique-id/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_unique_id"
 repository = "https://github.com/zng-ui/zng"
@@ -13,7 +13,9 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
 default = ["named", "bytemuck" ]
+# Enable associated names for ID types.
 named = ["dep:zng-txt", "dep:parking_lot"]
+# Derive `bytemuck` for ID types.
 bytemuck = []
 
 [dependencies]
diff --git a/zng-unique-id/README.md b/zng-unique-id/README.md
new file mode 100644
index 000000000..d7cead618
--- /dev/null
+++ b/zng-unique-id/README.md
@@ -0,0 +1,22 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 2 enabled by default.
+
+#### `"named"`
+Enable associated names for ID types.
+
+*Enabled by default.*
+
+#### `"bytemuck"`
+Derive `bytemuck` for ID types.
+
+*Enabled by default.*
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-unique-id/src/lib.rs b/zng-unique-id/src/lib.rs
index 70af54ebc..0ce1bd70b 100644
--- a/zng-unique-id/src/lib.rs
+++ b/zng-unique-id/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Macros for generating unique ID types.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-unit/Cargo.toml b/zng-unit/Cargo.toml
index d672da002..20357db2e 100644
--- a/zng-unit/Cargo.toml
+++ b/zng-unit/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_unit"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-unit/README.md b/zng-unit/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-unit/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-unit/src/lib.rs b/zng-unit/src/lib.rs
index 89d6f4650..94a27cfbf 100644
--- a/zng-unit/src/lib.rs
+++ b/zng-unit/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Base unit types.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-var-proc-macros/Cargo.toml b/zng-var-proc-macros/Cargo.toml
index b920781a1..9e5e3cfd1 100644
--- a/zng-var-proc-macros/Cargo.toml
+++ b/zng-var-proc-macros/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.4"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_var_proc_macros"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-var-proc-macros/README.md b/zng-var-proc-macros/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-var-proc-macros/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-var-proc-macros/src/lib.rs b/zng-var-proc-macros/src/lib.rs
index 0ea4def15..ce9be2b5d 100644
--- a/zng-var-proc-macros/src/lib.rs
+++ b/zng-var-proc-macros/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Proc-macros for the `zng-var` crate.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-var/Cargo.toml b/zng-var/Cargo.toml
index 7915c87b0..989ed33ad 100644
--- a/zng-var/Cargo.toml
+++ b/zng-var/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.5"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_var"
 repository = "https://github.com/zng-ui/zng"
@@ -14,9 +14,7 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 [features]
 default = ["debug_default"]
 
-# Signal the build script to enable the `"dyn_*"` features for debug builds.
-#
-# Enabled by default.
+# Signal the build script to enable the `"dyn_*"` features in debug builds.
 debug_default = []
 
 # Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
diff --git a/zng-var/README.md b/zng-var/README.md
new file mode 100644
index 000000000..0e0a4f454
--- /dev/null
+++ b/zng-var/README.md
@@ -0,0 +1,22 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 1 enabled by default.
+
+#### `"debug_default"`
+Signal the build script to enable the `"dyn_*"` features in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-var/src/lib.rs b/zng-var/src/lib.rs
index e00b17313..b6a6b7360 100644
--- a/zng-var/src/lib.rs
+++ b/zng-var/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Batch updated variables in an app context.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
 #![warn(unused_extern_crates)]
diff --git a/zng-view-api/Cargo.toml b/zng-view-api/Cargo.toml
index 42e6a00ab..43a9a921b 100644
--- a/zng-view-api/Cargo.toml
+++ b/zng-view-api/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_view_api"
 repository = "https://github.com/zng-ui/zng"
@@ -14,7 +14,7 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 [features]
 default = ["ipc"]
 
-# Enables creation of separate or pre-build view, enabled by default.
+# Enables creation of separate or pre-build view.
 #
 # When this is enabled communication with the view is (de)serialized which can add a 
 # minor cost, something like a 1ms per 3MB frame request.
diff --git a/zng-view-api/README.md b/zng-view-api/README.md
new file mode 100644
index 000000000..a90778670
--- /dev/null
+++ b/zng-view-api/README.md
@@ -0,0 +1,23 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 1 enabled by default.
+
+#### `"ipc"`
+Enables creation of separate or pre-build view.
+
+When this is enabled communication with the view is (de)serialized which can add a
+minor cost, something like a 1ms per 3MB frame request.
+
+*Enabled by default.*
+
+#### `"var"`
+Implement `IntoVar<T>` for API types.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-view-api/src/lib.rs b/zng-view-api/src/lib.rs
index 58886a198..488ff7f63 100644
--- a/zng-view-api/src/lib.rs
+++ b/zng-view-api/src/lib.rs
@@ -1,6 +1,5 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! The View Process API.
 //!
@@ -13,7 +12,9 @@
 //! The [`VERSION`] of this crate must match exactly in both *App-Process* and *View-Process*, otherwise a runtime
 //! panic error is generated.
 //!
-
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(missing_docs)]
 #![warn(unused_extern_crates)]
 
diff --git a/zng-view-prebuilt/Cargo.toml b/zng-view-prebuilt/Cargo.toml
index cf396da1a..145c13f63 100644
--- a/zng-view-prebuilt/Cargo.toml
+++ b/zng-view-prebuilt/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.3.3"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_view_prebuilt"
 repository = "https://github.com/zng-ui/zng"
@@ -15,8 +15,6 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 default = ["embedded"]
 
 # Requires embedded on build, if prebuilt is not in './lib' and download fails the build will fail.
-#
-# This is enabled by default.
 embedded = []
 
 [dependencies]
diff --git a/zng-view-prebuilt/README.md b/zng-view-prebuilt/README.md
new file mode 100644
index 000000000..929ce5b49
--- /dev/null
+++ b/zng-view-prebuilt/README.md
@@ -0,0 +1,16 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+ This crate provides 1 feature flag, enabled by default.
+#### `"embedded"`
+Requires embedded on build, if prebuilt is not in './lib' and download fails the build will fail.
+
+*Enabled by default.*
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-view-prebuilt/src/lib.rs b/zng-view-prebuilt/src/lib.rs
index 377cb31f4..c2d0b2f60 100644
--- a/zng-view-prebuilt/src/lib.rs
+++ b/zng-view-prebuilt/src/lib.rs
@@ -1,11 +1,13 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Dynamically links to [`zng-view`] pre-built library.
 //!
 //! [`zng-view`]: https://docs.rs/zng-view
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-view/Cargo.toml b/zng-view/Cargo.toml
index 2d1aa13e5..3286425d8 100644
--- a/zng-view/Cargo.toml
+++ b/zng-view/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_view"
 repository = "https://github.com/zng-ui/zng"
@@ -18,15 +18,11 @@ default = ["ipc", "software"]
 #
 # If this is enabled all communication with the view is serialized/deserialized, 
 # even in same-process mode.
-#
-# Feature enabled by default.
 ipc = ["zng-view-api/ipc"]
 
 # Enables software renderer fallback.
 #
 # If enabled and a native OpenGL 3.2 driver is not available the `swgl` software renderer is used.
-#
-# Feature enabled by default.
 software = ["dep:swgl"]
 
 # Bundle third party licenses.
diff --git a/zng-view/README.md b/zng-view/README.md
new file mode 100644
index 000000000..882b391b2
--- /dev/null
+++ b/zng-view/README.md
@@ -0,0 +1,34 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 3 feature flags, 2 enabled by default.
+
+#### `"ipc"`
+Enables pre-build and init as view-process.
+
+If this is enabled all communication with the view is serialized/deserialized,
+even in same-process mode.
+
+*Enabled by default.*
+
+#### `"software"`
+Enables software renderer fallback.
+
+If enabled and a native OpenGL 3.2 driver is not available the `swgl` software renderer is used.
+
+*Enabled by default.*
+
+#### `"bundle_licenses"`
+Bundle third party licenses.
+
+Needs `cargo-about` and Internet connection during build.
+
+Not enabled by default. Note that `"view_prebuilt"` always bundles licenses.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-view/src/lib.rs b/zng-view/src/lib.rs
index 8fe26baa2..a8a8e8916 100644
--- a/zng-view/src/lib.rs
+++ b/zng-view/src/lib.rs
@@ -1,10 +1,9 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
-//! View-Process implementation using [`glutin`].
+//! View-Process implementation.
 //!
-//! This backend supports headed and headless apps.
+//! This implementation supports headed and headless apps in Windows, Linux and MacOS.
 //!
 //! # Usage
 //!
@@ -95,9 +94,11 @@
 //!
 //! You can also inject your own extensions, see the [`extensions`] module for more details.
 //!
-//! [`glutin`]: https://docs.rs/glutin/
-//! [`zng-view-prebuilt`]: https://docs.rs/zng-view-prebuilt/
-
+//! [`zng-view-prebuilt`]: https://crates.io/crates/zng-view-prebuilt/
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![allow(clippy::needless_doctest_main)]
 #![doc(test(no_crate_inject))]
 #![warn(missing_docs)]
diff --git a/zng-wgt-access/Cargo.toml b/zng-wgt-access/Cargo.toml
index 7a5a4a240..c5ac4e997 100644
--- a/zng-wgt-access/Cargo.toml
+++ b/zng-wgt-access/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_access"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-access/README.md b/zng-wgt-access/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-access/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-access/src/lib.rs b/zng-wgt-access/src/lib.rs
index 64815d9ec..bb2b8b7a0 100644
--- a/zng-wgt-access/src/lib.rs
+++ b/zng-wgt-access/src/lib.rs
@@ -1,7 +1,5 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
-//!
 //! Properties that define accessibility metadata.
 //!
 //! The properties in this crate should only be used by widget implementers, they only
@@ -13,7 +11,10 @@
 //! [`AccessRole::Button`]: zng_app::widget::info::access::AccessRole::Button
 //! [`AccessRole::TabList`]: zng_app::widget::info::access::AccessRole::TabList
 //! [`AccessRole::Tab`]: zng_app::widget::info::access::AccessRole::Tab
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-ansi-text/Cargo.toml b/zng-wgt-ansi-text/Cargo.toml
index 85c52ef19..efd66fd63 100644
--- a/zng-wgt-ansi-text/Cargo.toml
+++ b/zng-wgt-ansi-text/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_ansi_text"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-ansi-text/README.md b/zng-wgt-ansi-text/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-ansi-text/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-ansi-text/src/lib.rs b/zng-wgt-ansi-text/src/lib.rs
index a9a3cc4e2..f4c586bcd 100644
--- a/zng-wgt-ansi-text/src/lib.rs
+++ b/zng-wgt-ansi-text/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! ANSI text widget, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-button/Cargo.toml b/zng-wgt-button/Cargo.toml
index 6f861c7e5..23e225e48 100644
--- a/zng-wgt-button/Cargo.toml
+++ b/zng-wgt-button/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_button"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-button/README.md b/zng-wgt-button/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-button/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-button/src/lib.rs b/zng-wgt-button/src/lib.rs
index ca55c1623..a61617e1e 100644
--- a/zng-wgt-button/src/lib.rs
+++ b/zng-wgt-button/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Button widget.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-checkerboard/Cargo.toml b/zng-wgt-checkerboard/Cargo.toml
index 3596b2b8d..4fc74ec12 100644
--- a/zng-wgt-checkerboard/Cargo.toml
+++ b/zng-wgt-checkerboard/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_checkerboard"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-checkerboard/README.md b/zng-wgt-checkerboard/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-checkerboard/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-checkerboard/src/lib.rs b/zng-wgt-checkerboard/src/lib.rs
index 86c30e10c..7461b1cf5 100644
--- a/zng-wgt-checkerboard/src/lib.rs
+++ b/zng-wgt-checkerboard/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Checkerboard widget, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-container/Cargo.toml b/zng-wgt-container/Cargo.toml
index ae4b5eb0a..d6d07d603 100644
--- a/zng-wgt-container/Cargo.toml
+++ b/zng-wgt-container/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_container"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-container/README.md b/zng-wgt-container/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-container/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-container/src/lib.rs b/zng-wgt-container/src/lib.rs
index 2b41b90c3..41997a054 100644
--- a/zng-wgt-container/src/lib.rs
+++ b/zng-wgt-container/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Base container widget and properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-data-view/Cargo.toml b/zng-wgt-data-view/Cargo.toml
index fd5bd318e..be269a348 100644
--- a/zng-wgt-data-view/Cargo.toml
+++ b/zng-wgt-data-view/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_data_view"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-data-view/README.md b/zng-wgt-data-view/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-data-view/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-data-view/src/lib.rs b/zng-wgt-data-view/src/lib.rs
index 27284c956..891685179 100644
--- a/zng-wgt-data-view/src/lib.rs
+++ b/zng-wgt-data-view/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Data view widget.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-data/Cargo.toml b/zng-wgt-data/Cargo.toml
index f83c32983..5c36e564a 100644
--- a/zng-wgt-data/Cargo.toml
+++ b/zng-wgt-data/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_data"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-data/README.md b/zng-wgt-data/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-data/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-data/src/lib.rs b/zng-wgt-data/src/lib.rs
index f4a58351c..6b518a2cf 100644
--- a/zng-wgt-data/src/lib.rs
+++ b/zng-wgt-data/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Contextual [`DATA`] and validation.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-fill/Cargo.toml b/zng-wgt-fill/Cargo.toml
index ab23f00be..5334c429f 100644
--- a/zng-wgt-fill/Cargo.toml
+++ b/zng-wgt-fill/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_fill"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-fill/README.md b/zng-wgt-fill/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-fill/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-fill/src/lib.rs b/zng-wgt-fill/src/lib.rs
index 5ac146ac4..b9cec43e5 100644
--- a/zng-wgt-fill/src/lib.rs
+++ b/zng-wgt-fill/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Properties that fill the widget inner bounds and nodes that fill the available space.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-filter/Cargo.toml b/zng-wgt-filter/Cargo.toml
index c2cd0bb5e..b3ba3a355 100644
--- a/zng-wgt-filter/Cargo.toml
+++ b/zng-wgt-filter/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_filter"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-filter/README.md b/zng-wgt-filter/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-filter/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-filter/src/lib.rs b/zng-wgt-filter/src/lib.rs
index 77305763d..13753be66 100644
--- a/zng-wgt-filter/src/lib.rs
+++ b/zng-wgt-filter/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Color filter properties, [`opacity`](fn@opacity), [`filter`](fn@filter) and more.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-grid/Cargo.toml b/zng-wgt-grid/Cargo.toml
index eff88af1e..1d6aec5b5 100644
--- a/zng-wgt-grid/Cargo.toml
+++ b/zng-wgt-grid/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_grid"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-grid/README.md b/zng-wgt-grid/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-grid/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-grid/src/lib.rs b/zng-wgt-grid/src/lib.rs
index f37e5bd5a..f9a4fd4ca 100644
--- a/zng-wgt-grid/src/lib.rs
+++ b/zng-wgt-grid/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Grid widgets, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-image/Cargo.toml b/zng-wgt-image/Cargo.toml
index ca8838c57..16f990c91 100644
--- a/zng-wgt-image/Cargo.toml
+++ b/zng-wgt-image/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_image"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-image/README.md b/zng-wgt-image/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-image/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-image/src/lib.rs b/zng-wgt-image/src/lib.rs
index 699b0ac52..095f25089 100644
--- a/zng-wgt-image/src/lib.rs
+++ b/zng-wgt-image/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Image widget, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-input/Cargo.toml b/zng-wgt-input/Cargo.toml
index 1c0d118ed..9c40ee088 100644
--- a/zng-wgt-input/Cargo.toml
+++ b/zng-wgt-input/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_input"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-input/README.md b/zng-wgt-input/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-input/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-input/src/lib.rs b/zng-wgt-input/src/lib.rs
index 1b7a31c8e..73d28e5cc 100644
--- a/zng-wgt-input/src/lib.rs
+++ b/zng-wgt-input/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Input events and focus properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-inspector/Cargo.toml b/zng-wgt-inspector/Cargo.toml
index 24c5f914e..cc2cce290 100644
--- a/zng-wgt-inspector/Cargo.toml
+++ b/zng-wgt-inspector/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_inspector"
 repository = "https://github.com/zng-ui/zng"
@@ -13,7 +13,9 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
 default = ["debug_default"]
+# Enables the `"live"` feature in debug builds.
 debug_default = []
+# Compiles the interactive inspector.
 live = []
 
 [dependencies]
diff --git a/zng-wgt-inspector/README.md b/zng-wgt-inspector/README.md
new file mode 100644
index 000000000..3d26584fd
--- /dev/null
+++ b/zng-wgt-inspector/README.md
@@ -0,0 +1,20 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 1 enabled by default.
+
+#### `"debug_default"`
+Enables the `"live"` feature in debug builds.
+
+*Enabled by default.*
+
+#### `"live"`
+Compiles the interactive inspector.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-wgt-inspector/src/lib.rs b/zng-wgt-inspector/src/lib.rs
index 31d282a22..cf5546da6 100644
--- a/zng-wgt-inspector/src/lib.rs
+++ b/zng-wgt-inspector/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Debug properties and inspector implementation.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-layer/Cargo.toml b/zng-wgt-layer/Cargo.toml
index dd1b10914..715c1cc81 100644
--- a/zng-wgt-layer/Cargo.toml
+++ b/zng-wgt-layer/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_layer"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-layer/README.md b/zng-wgt-layer/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-layer/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-layer/src/lib.rs b/zng-wgt-layer/src/lib.rs
index 28cda40ad..4f130ccbc 100644
--- a/zng-wgt-layer/src/lib.rs
+++ b/zng-wgt-layer/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Window layers and popup.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-markdown/Cargo.toml b/zng-wgt-markdown/Cargo.toml
index 6745fb88e..05f4cd1e2 100644
--- a/zng-wgt-markdown/Cargo.toml
+++ b/zng-wgt-markdown/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_markdown"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-markdown/README.md b/zng-wgt-markdown/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-markdown/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-markdown/src/lib.rs b/zng-wgt-markdown/src/lib.rs
index 4a2c8542c..e05b9673d 100644
--- a/zng-wgt-markdown/src/lib.rs
+++ b/zng-wgt-markdown/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Markdown widget, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-material-icons/Cargo.toml b/zng-wgt-material-icons/Cargo.toml
index 8cf5f1686..939fe6663 100644
--- a/zng-wgt-material-icons/Cargo.toml
+++ b/zng-wgt-material-icons/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_material_icons"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-material-icons/README.md b/zng-wgt-material-icons/README.md
new file mode 100644
index 000000000..169806bda
--- /dev/null
+++ b/zng-wgt-material-icons/README.md
@@ -0,0 +1,37 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 5 feature flags, 5 enabled by default.
+
+#### `"embedded"`
+Embedded font files.
+
+*Enabled by default.*
+
+#### `"outlined"`
+Outlined icon set.
+
+*Enabled by default.*
+
+#### `"filled"`
+Filled icon set.
+
+*Enabled by default.*
+
+#### `"rounded"`
+Rounded icon set.
+
+*Enabled by default.*
+
+#### `"sharp"`
+Sharp icon set.
+
+*Enabled by default.*
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-wgt-material-icons/src/lib.rs b/zng-wgt-material-icons/src/lib.rs
index d16f6af01..7ce2af472 100644
--- a/zng-wgt-material-icons/src/lib.rs
+++ b/zng-wgt-material-icons/src/lib.rs
@@ -1,6 +1,5 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Material icons for the [`Icon!`] widget.
 //!
@@ -11,7 +10,10 @@
 //!
 //! [`Icon!`]: struct@zng_wgt_text::icon::Icon
 //! [Material Design Icons]: https://github.com/google/material-design-icons
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-menu/Cargo.toml b/zng-wgt-menu/Cargo.toml
index 31b0d7e9f..3ef9eda66 100644
--- a/zng-wgt-menu/Cargo.toml
+++ b/zng-wgt-menu/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_menu"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-menu/README.md b/zng-wgt-menu/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-menu/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-menu/src/lib.rs b/zng-wgt-menu/src/lib.rs
index 4ac9c7925..b78872fd1 100644
--- a/zng-wgt-menu/src/lib.rs
+++ b/zng-wgt-menu/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Menu widgets and properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-panel/Cargo.toml b/zng-wgt-panel/Cargo.toml
index 7d0301ada..d1434dd2c 100644
--- a/zng-wgt-panel/Cargo.toml
+++ b/zng-wgt-panel/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_panel"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-panel/README.md b/zng-wgt-panel/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-panel/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-panel/src/lib.rs b/zng-wgt-panel/src/lib.rs
index 938d18cdf..09be36810 100644
--- a/zng-wgt-panel/src/lib.rs
+++ b/zng-wgt-panel/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Panel widget and properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-rule-line/Cargo.toml b/zng-wgt-rule-line/Cargo.toml
index 3f3eb1252..697b1f538 100644
--- a/zng-wgt-rule-line/Cargo.toml
+++ b/zng-wgt-rule-line/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_rule_line"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-rule-line/README.md b/zng-wgt-rule-line/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-rule-line/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-rule-line/src/lib.rs b/zng-wgt-rule-line/src/lib.rs
index 7fee96f44..979f0edb2 100644
--- a/zng-wgt-rule-line/src/lib.rs
+++ b/zng-wgt-rule-line/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Rule line widgets.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-scroll/Cargo.toml b/zng-wgt-scroll/Cargo.toml
index 8b8649e44..4396d0aa2 100644
--- a/zng-wgt-scroll/Cargo.toml
+++ b/zng-wgt-scroll/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_scroll"
 repository = "https://github.com/zng-ui/zng"
@@ -13,7 +13,11 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
 default = ["debug_default"]
+# Enables the `"dyn_closure"` in debug builds.
 debug_default = []
+# Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+#
+# This speeds-up compilation time at the cost of runtime.
 dyn_closure = []
 
 [dependencies]
diff --git a/zng-wgt-scroll/README.md b/zng-wgt-scroll/README.md
new file mode 100644
index 000000000..8bff0784f
--- /dev/null
+++ b/zng-wgt-scroll/README.md
@@ -0,0 +1,22 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 1 enabled by default.
+
+#### `"debug_default"`
+Enables the `"dyn_closure"` in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-wgt-scroll/src/lib.rs b/zng-wgt-scroll/src/lib.rs
index 1d56246bb..2208a38f2 100644
--- a/zng-wgt-scroll/src/lib.rs
+++ b/zng-wgt-scroll/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Scroll widgets, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-size-offset/Cargo.toml b/zng-wgt-size-offset/Cargo.toml
index 834389d86..ee32cd785 100644
--- a/zng-wgt-size-offset/Cargo.toml
+++ b/zng-wgt-size-offset/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_size_offset"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-size-offset/README.md b/zng-wgt-size-offset/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-size-offset/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-size-offset/src/lib.rs b/zng-wgt-size-offset/src/lib.rs
index d0a146ebf..b69d5e65f 100644
--- a/zng-wgt-size-offset/src/lib.rs
+++ b/zng-wgt-size-offset/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Exact size constraints and exact positioning properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-stack/Cargo.toml b/zng-wgt-stack/Cargo.toml
index 4145ba254..7b0adde54 100644
--- a/zng-wgt-stack/Cargo.toml
+++ b/zng-wgt-stack/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_stack"
 repository = "https://github.com/zng-ui/zng"
@@ -13,7 +13,11 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
 default = ["debug_default"]
+# Enables the `"dyn_closure"` in debug builds.
 debug_default = []
+# Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+#
+# This speeds-up compilation time at the cost of runtime.
 dyn_closure = []
 
 [dependencies]
diff --git a/zng-wgt-stack/README.md b/zng-wgt-stack/README.md
new file mode 100644
index 000000000..8bff0784f
--- /dev/null
+++ b/zng-wgt-stack/README.md
@@ -0,0 +1,22 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 1 enabled by default.
+
+#### `"debug_default"`
+Enables the `"dyn_closure"` in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-wgt-stack/src/lib.rs b/zng-wgt-stack/src/lib.rs
index 3a6be4845..5b3bc3ee8 100644
--- a/zng-wgt-stack/src/lib.rs
+++ b/zng-wgt-stack/src/lib.rs
@@ -1,8 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Stack widgets, properties and nodes.
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 
 zng_wgt::enable_widget_macros!();
 
diff --git a/zng-wgt-style/Cargo.toml b/zng-wgt-style/Cargo.toml
index 7077a64d9..8422c0a57 100644
--- a/zng-wgt-style/Cargo.toml
+++ b/zng-wgt-style/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_style"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-style/README.md b/zng-wgt-style/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-style/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-style/src/lib.rs b/zng-wgt-style/src/lib.rs
index c2cc4486a..3f8f482a5 100644
--- a/zng-wgt-style/src/lib.rs
+++ b/zng-wgt-style/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Style building blocks.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 // suppress nag about very simple boxed closure signatures.
diff --git a/zng-wgt-text-input/Cargo.toml b/zng-wgt-text-input/Cargo.toml
index 7e864579f..b3f01465c 100644
--- a/zng-wgt-text-input/Cargo.toml
+++ b/zng-wgt-text-input/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_text_input"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-text-input/README.md b/zng-wgt-text-input/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-text-input/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-text-input/src/lib.rs b/zng-wgt-text-input/src/lib.rs
index 84fbe46a9..d647ae494 100644
--- a/zng-wgt-text-input/src/lib.rs
+++ b/zng-wgt-text-input/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Text input and label widgets.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-text/Cargo.toml b/zng-wgt-text/Cargo.toml
index 20e3065ab..4fc4bf690 100644
--- a/zng-wgt-text/Cargo.toml
+++ b/zng-wgt-text/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_text"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-text/README.md b/zng-wgt-text/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-text/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-text/src/lib.rs b/zng-wgt-text/src/lib.rs
index 93357548d..6a1373a86 100644
--- a/zng-wgt-text/src/lib.rs
+++ b/zng-wgt-text/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Text widgets and properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
 #![warn(unused_extern_crates)]
diff --git a/zng-wgt-toggle/Cargo.toml b/zng-wgt-toggle/Cargo.toml
index e593f98ab..5e8120a2c 100644
--- a/zng-wgt-toggle/Cargo.toml
+++ b/zng-wgt-toggle/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_toggle"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-toggle/README.md b/zng-wgt-toggle/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-toggle/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-toggle/src/lib.rs b/zng-wgt-toggle/src/lib.rs
index 0e97c7c65..81f74576c 100644
--- a/zng-wgt-toggle/src/lib.rs
+++ b/zng-wgt-toggle/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Toggle widget, properties and commands.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-tooltip/Cargo.toml b/zng-wgt-tooltip/Cargo.toml
index f78347907..f147c2d70 100644
--- a/zng-wgt-tooltip/Cargo.toml
+++ b/zng-wgt-tooltip/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_tooltip"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-tooltip/README.md b/zng-wgt-tooltip/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-tooltip/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-tooltip/src/lib.rs b/zng-wgt-tooltip/src/lib.rs
index 2e1fcc217..932de3422 100644
--- a/zng-wgt-tooltip/src/lib.rs
+++ b/zng-wgt-tooltip/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Tooltip widget, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-transform/Cargo.toml b/zng-wgt-transform/Cargo.toml
index e96b847ef..001c3bada 100644
--- a/zng-wgt-transform/Cargo.toml
+++ b/zng-wgt-transform/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_transform"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-transform/README.md b/zng-wgt-transform/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-transform/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-transform/src/lib.rs b/zng-wgt-transform/src/lib.rs
index 205bd6c1a..4ea4fef1e 100644
--- a/zng-wgt-transform/src/lib.rs
+++ b/zng-wgt-transform/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Transform properties, [`scale`](fn@scale), [`rotate`](fn@rotate), [`transform`](fn@transform) and more.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-undo-history/Cargo.toml b/zng-wgt-undo-history/Cargo.toml
index 6b61cbc11..25caa70ca 100644
--- a/zng-wgt-undo-history/Cargo.toml
+++ b/zng-wgt-undo-history/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_undo_history"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-undo-history/README.md b/zng-wgt-undo-history/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-undo-history/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-undo-history/src/lib.rs b/zng-wgt-undo-history/src/lib.rs
index 569647ca8..3dc00ddea 100644
--- a/zng-wgt-undo-history/src/lib.rs
+++ b/zng-wgt-undo-history/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Undo history widget.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-undo/Cargo.toml b/zng-wgt-undo/Cargo.toml
index 3145b43ae..c80e3adf4 100644
--- a/zng-wgt-undo/Cargo.toml
+++ b/zng-wgt-undo/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_undo"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-undo/README.md b/zng-wgt-undo/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-undo/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-undo/src/lib.rs b/zng-wgt-undo/src/lib.rs
index 84d7466f2..5e54afa26 100644
--- a/zng-wgt-undo/src/lib.rs
+++ b/zng-wgt-undo/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Undo properties.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-webrender-debug/Cargo.toml b/zng-wgt-webrender-debug/Cargo.toml
index 567288ebe..f185b4135 100644
--- a/zng-wgt-webrender-debug/Cargo.toml
+++ b/zng-wgt-webrender-debug/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_webrender_debug"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-webrender-debug/README.md b/zng-wgt-webrender-debug/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-webrender-debug/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-webrender-debug/src/lib.rs b/zng-wgt-webrender-debug/src/lib.rs
index 12ba11e84..e2c5b62ac 100644
--- a/zng-wgt-webrender-debug/src/lib.rs
+++ b/zng-wgt-webrender-debug/src/lib.rs
@@ -1,8 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Webrender debug flags property for use with `zng-view` view-process.
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 
 pub use webrender_api::DebugFlags;
 
diff --git a/zng-wgt-window/Cargo.toml b/zng-wgt-window/Cargo.toml
index 5c6266a1f..59e46ebc5 100644
--- a/zng-wgt-window/Cargo.toml
+++ b/zng-wgt-window/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_window"
 repository = "https://github.com/zng-ui/zng"
@@ -13,7 +13,9 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 
 [features]
 default = ["debug_default"]
+# Enable the `zng-wgt` crate debug defaults.
 debug_default = ["zng-wgt/debug_default"]
+# Enable the `zng-wgt` crate dynamic closures.
 dyn_closure = ["zng-wgt/dyn_closure"]
 
 [dependencies]
diff --git a/zng-wgt-window/README.md b/zng-wgt-window/README.md
new file mode 100644
index 000000000..dbb3479c7
--- /dev/null
+++ b/zng-wgt-window/README.md
@@ -0,0 +1,20 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 2 feature flags, 1 enabled by default.
+
+#### `"debug_default"`
+Enable the `zng-wgt` crate debug defaults.
+
+*Enabled by default.*
+
+#### `"dyn_closure"`
+Enable the `zng-wgt` crate dynamic closures.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-wgt-window/src/lib.rs b/zng-wgt-window/src/lib.rs
index 6c5208435..a956327bc 100644
--- a/zng-wgt-window/src/lib.rs
+++ b/zng-wgt-window/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Window widget, properties, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt-wrap/Cargo.toml b/zng-wgt-wrap/Cargo.toml
index a9d312b9e..ed6260f19 100644
--- a/zng-wgt-wrap/Cargo.toml
+++ b/zng-wgt-wrap/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.8"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt_wrap"
 repository = "https://github.com/zng-ui/zng"
diff --git a/zng-wgt-wrap/README.md b/zng-wgt-wrap/README.md
new file mode 100644
index 000000000..bf784cf50
--- /dev/null
+++ b/zng-wgt-wrap/README.md
@@ -0,0 +1,7 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+
+
diff --git a/zng-wgt-wrap/src/lib.rs b/zng-wgt-wrap/src/lib.rs
index 2853cb354..d267dbc83 100644
--- a/zng-wgt-wrap/src/lib.rs
+++ b/zng-wgt-wrap/src/lib.rs
@@ -1,9 +1,11 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Wrap panel, properties and nodes.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
diff --git a/zng-wgt/Cargo.toml b/zng-wgt/Cargo.toml
index d521f64c4..20691f993 100644
--- a/zng-wgt/Cargo.toml
+++ b/zng-wgt/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.2.7"
 authors = ["The Zng Project Developers"]
 edition = "2021"
 license = "Apache-2.0 OR MIT"
-readme = "../zng-app/README.md"
+readme = "README.md"
 description = "Part of the zng project."
 documentation = "https://zng-ui.github.io/doc/zng_wgt"
 repository = "https://github.com/zng-ui/zng"
@@ -14,9 +14,7 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 [features]
 default = ["debug_default"]
 
-# Signal the build script to enable the `"dyn_*"`, `"inspector"` and `"trace_widget"` features for debug builds.
-#
-# Enabled by default.
+# Signal the build script to enable the `"dyn_*"`, `"inspector"` and `"trace_widget"` features in debug builds.
 debug_default = ["zng-var/debug_default"]
 
 # Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
diff --git a/zng-wgt/README.md b/zng-wgt/README.md
new file mode 100644
index 000000000..e4731400d
--- /dev/null
+++ b/zng-wgt/README.md
@@ -0,0 +1,25 @@
+<!--do doc --readme header-->
+This crate is part of the [`zng`](https://github.com/zng-ui/zng?tab=readme-ov-file#crates) project.
+
+
+<!--do doc --readme features-->
+## Cargo Features
+
+This crate provides 3 feature flags, 1 enabled by default.
+
+#### `"debug_default"`
+Signal the build script to enable the `"dyn_*"`, `"inspector"` and `"trace_widget"` features in debug builds.
+
+*Enabled by default.*
+
+#### `"dyn_closure"`
+Box closures at opportune places, such as `Var::map`, reducing the number of monomorphised types.
+
+This speeds-up compilation time at the cost of runtime.
+
+#### `"http"`
+Enable web tasks.
+
+<!--do doc --readme #SECTION-END-->
+
+
diff --git a/zng-wgt/src/lib.rs b/zng-wgt/src/lib.rs
index ac3935236..897590c2d 100644
--- a/zng-wgt/src/lib.rs
+++ b/zng-wgt/src/lib.rs
@@ -1,13 +1,15 @@
 #![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo-icon.png")]
 #![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/master/examples/res/image/zng-logo.png")]
-#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 //!
 //! Basic widget properties and helpers for declaring widgets and properties.
 //!
 //! # Widget Instantiation
 //!
 //! See [`enable_widget_macros!`] if you want to instantiate widgets without depending on the `zng` crate.
-
+//!
+//! # Crate
+//!
+#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
 // suppress nag about very simple boxed closure signatures.
 #![allow(clippy::type_complexity)]
 #![warn(unused_extern_crates)]
diff --git a/zng/Cargo.toml b/zng/Cargo.toml
index fe5ce8cb3..c2ede3185 100644
--- a/zng/Cargo.toml
+++ b/zng/Cargo.toml
@@ -14,17 +14,15 @@ keywords = ["gui", "ui", "user-interface", "zng"]
 [features]
 default = ["ipc", "debug_default", "view_software"]
 
-# Enables pre-build views and connecting to views running in another process.
-# 
-# Enabled by default.
-ipc = ["zng-app/ipc", "zng-view-api/ipc", "zng-view?/ipc"]
+# Include the default view-process implementation.
+view = ["dep:zng-view"]
+# Include the default view-process implementation as an embedded precompiled binary.
+view_prebuilt = ["dep:zng-view-prebuilt", "ipc"]
 
-# Enables http tasks.
+# Enables HTTP tasks and web features of widgets and services.
 http = ["zng-task/http", "zng-wgt/http", "zng-ext-image/http"]
 
-# Enable the `"dyn_*"`, `"inspector"` features for debug builds only.
-#
-# Enabled by default.
+# Enable the `"dyn_*"`, `"inspector"` features in debug builds.
 debug_default = [
     "zng-app/debug_default",
     "zng-wgt-inspector/debug_default",
@@ -56,11 +54,6 @@ dyn_closure = [
 ]
 
 # Test utilities.
-#
-# USAGE:
-#
-# Build with this feature to use the core test helper types that show
-# in the documentation.
 test_util = ["zng-app/test_util", "zng-ext-window/test_util"]
 
 # Allows multiple app instances per-process.
@@ -81,21 +74,15 @@ trace_widget = ["zng-app/trace_widget"]
 trace_wgt_item = ["zng-app/trace_wgt_item"]
 
 # Spawns a thread on app creation that checks and prints `parking_lot` deadlocks.
-#
-# Not enabled by default.
 deadlock_detection = ["zng-app/deadlock_detection"]
 
 # Embed hyphenation dictionaries for all supported languages.
 #
 # If enabled some 2.8MB of data is embedded, you can provide an alternative dictionary source using the 
 # `Hyphenation::dictionary_source` method.
-#
-# Not enabled by default.
 hyphenation_embed_all = ["zng-ext-font/hyphenation_embed_all"]
 
 # Include all Material Icons icon sets in the default app.
-#
-# Not enabled by default.
 material_icons = [
     "material_icons_outlined",
     "material_icons_filled",
@@ -105,8 +92,6 @@ material_icons = [
 # Material Icons Outlined icon set.
 #
 # If enabled some icons of this set are used for some of the commands.
-#
-# Not enabled by default.
 material_icons_outlined = [
     "dep:zng-wgt-material-icons",
     "zng-wgt-material-icons/embedded",
@@ -114,8 +99,6 @@ material_icons_outlined = [
 ]
 
 # Material Icons Filled icon set.
-#
-# Not enabled by default.
 material_icons_filled = [
     "dep:zng-wgt-material-icons",
     "zng-wgt-material-icons/embedded",
@@ -123,8 +106,6 @@ material_icons_filled = [
 ]
 
 # Material Icons Rounded icon set.
-#
-# Not enabled by default.
 material_icons_rounded = [
     "dep:zng-wgt-material-icons",
     "zng-wgt-material-icons/embedded",
@@ -132,8 +113,6 @@ material_icons_rounded = [
 ]
 
 # Material Icons Sharp icon set.
-#
-# Not enabled by default.
 material_icons_sharp = [
     "dep:zng-wgt-material-icons",
     "zng-wgt-material-icons/embedded",
@@ -147,13 +126,9 @@ ron = ["zng-ext-config/ron"]
 # Enable YAML configs.
 yaml = ["zng-ext-config/yaml"]
 
-# Include the default view-process implementation.
-view = ["dep:zng-view"]
 # Enables software renderer fallback in the default view-process.
 #
 # If enabled and a native OpenGL 3.2 driver is not available the `swgl` software renderer is used.
-#
-# Feature enabled by default.
 view_software = ["zng-view?/software"]
 # Collects and bundles third-party licenses used by the `zng-view` crate.
 #
@@ -162,8 +137,8 @@ view_software = ["zng-view?/software"]
 # Not enabled by default. Note that `"view_prebuilt"` always bundles licenses.
 view_bundle_licenses = ["zng-view?/bundle_licenses"]
 
-# Include the default view-process implementation as an embedded precompiled binary.
-view_prebuilt = ["dep:zng-view-prebuilt", "ipc"]
+# Enables pre-build views and connecting to views running in another process.
+ipc = ["zng-app/ipc", "zng-view-api/ipc", "zng-view?/ipc"]
 
 [dependencies]
 # foundation
diff --git a/zng/src/lib.rs b/zng/src/lib.rs
index 15c8cc5f8..d0ddcb06e 100644
--- a/zng/src/lib.rs
+++ b/zng/src/lib.rs
@@ -439,6 +439,12 @@
 //! This crate level documentation only gives an overview required to start making apps using existing widgets and properties.
 //! All top-level modules in this crate contains in-depth documentation about their subject, of particular importance the
 //! [`app`], [`widget`], [`layout`] and [`render`] modules should give you a solid understanding of how everything works.
+//!
+//! ### Cargo Features
+//!
+//! See the [Cargo Features] section in the crate README for Cargo features documentation.
+//!
+//! [Cargo Features]: https://github.com/zng-ui/zng/blob/master/README.md#cargo-features
 
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]


Test patch: