A multiplatform site previewer, following the orchestrator CommanderTurtle/orc and reproducing the deploy topology locally. It reads
.github/config/deploy-*.fs, creates one rendered working mirror per
SourceFolder, launches each framework's own development server, and keeps the
mirrors synchronized while source files are saved.
It is separate from both ORC and the small one-tree orc-reactor. The ORC
checkout remains read-only.
Clone your repo, then natively preview 7 site frameworks, preserving realtime edits to the fsharp source-code. Runs on reactor topology. Just clone and build with cargo.
git clone https://github.com/CommanderTurtle/preview
cd preview
cargo build --releaseRequired on PATH:
- Rust/Cargo and .NET for the preview binary and ORC renderer;
- PowerShell (
pwsh, or Windows PowerShell via--powershell powershell.exe) for the visible server consoles; - uv for Zensical projects;
- Ruby 3.4 and Bundler for Jekyll and GitHub Pages projects;
- Bun for Vite projects.
Netdocs is installed into the shared preview state automatically. It does not
alter the user's global .NET or PATH configuration.
Ports are assigned in sorted SourceFolder order. The current ORC tree sorts
as app, blog, docs, lab, net, pages, vite. Ports do not need to
be numerically sorted, so an existing six-site layout can retain its URLs:
.\target\release\orc-preview.exe `
--repo C:\src\orc `
--output C:\preview\orc `
--ports 4000,4111,4222,4333,4666,4444,4555The output contains:
C:\preview\orc\
app\
blog\
docs\
lab\
net\
pages\
vite\
.orc-preview\ # launch scripts, manifests, and shared preview state
Each site folder is a deployment-like working mirror: rendered ORC files and
literal assets remain beside native framework output such as site, _site,
or dist. A startup reconciliation replaces only ORC-managed files, so native
dependency/build directories can remain warm.
One visible PowerShell console is opened per site. The existing framework
launchers bind to 0.0.0.0; Netdocs currently follows its upstream Kestrel
behavior and binds to loopback. The parent prints every loopback URL. Press
Ctrl+C in the parent console to close the complete process tree.
Use --render-only to create/reconcile mirrors and inspect the generated
launch scripts without opening servers.
Detection keeps the common deploy workflow's precedence:
appsettings.json— Netdocs;zensical.toml— a Python 3.12.10 uv environment, Zensical, andtomli-w;Gemfile— the project's Bundler/Jekyll environment;package.json— Bun and the package's Vite development script;- otherwise — implicit GitHub Pages/Jekyll.
A Netdocs target uses the upstream native self-contained executable and the
documented netdocs serve --config ./appsettings.json --port <port> flow. At
server startup, the shared preview cache checks the upstream latest-release
API and downloads a new Windows x64 or Linux x64 executable only when needed.
Multiple Netdocs targets share that installation and a startup lock, while
each target retains its own appsettings.json, docs/, configured siteDir,
watcher, and live-reload server.
The last case matters: ORC's app, lab, and pages targets are GitHub Pages
sites even though only pages currently renders an explicit _config.yml.
Only these otherwise-unclaimed targets use the shared, preview-only
github-pages bundle. Native Gemfile, Zensical, and Vite projects never enter
that compatibility path. The bundle supplies Pages behavior such as optional
front matter, default layouts, README indexes, relative links, and GitHub
Flavored Markdown. This is the local equivalent of the second Jekyll build
GitHub performs after ORC pushes a rendered tree to its target repository.
For an implicit Pages target, remote_theme: owner/repository[@ref] is resolved
to that Git repository. Supported default jekyll-theme-* selections resolve
to their official pages-themes repositories; an omitted selection uses the
GitHub Pages default pages-themes/primer. Identical selections share one
shallow checkout, and layered files use hard links where the filesystem
supports them. The preview refreshes each unique checkout once when it starts,
then layers only the theme's _layouts,
_includes, _sass, _data, and assets beneath the rendered site. Copying
is non-destructive: an ORC-rendered path always wins. Theme configuration,
Gemfiles, sample pages, and repository metadata are never imported, so a
theme cannot replace project configuration or content. Declared/default gem
theme settings remain active so their plugin dependencies load normally. For
a remote_theme, the server reads a preview-only copy of the ORC config with
only that fetch directive removed; the source _config.yml is not edited.
GitHub metadata uses the checkout's origin owner together with each
deployment's TargetRepo. Local-path clones are followed back to their
upstream checkout. If the owner cannot be inferred, set it explicitly before
starting:
$env:GITHUB_REPOSITORY_OWNER = "CommanderTurtle"The first implicit Pages launch installs the shared gem bundle. Later launches
reuse it. A project with its own Gemfile remains independent and uses its
native bundle. A theme Git checkout records the exact commit used and refreshes
on the next preview start. The launcher also carries a process-local Ruby 3.4
compatibility fix for the edit-link tag in the version of
jekyll-github-metadata pinned by GitHub Pages; no installed gem is modified.
Saving a file does not trigger a replacement build system. ORC overwrites only
the corresponding mirror file (or dependent pages after a helper change), and
Zensical, Jekyll, or Vite performs its normal rebuild/reload. A brief quiet
window coalesces editor save patterns and folder replacements; configure it
with --settle-ms.
Each deploy record's UseSharedStrings boolean is also honored locally. When
true, the preview loads that site's strings/sharedstrings.fs helper through
open SharedStrings before rendering its wrappers. Other sites are untouched,
and the helper never appears in their working mirrors.
When the deploy configuration itself changes, the parent shuts down cleanly. Restart it with a port for each newly discovered target.