FluxMarkdown is built from two independent layers — a native Swift QuickLook extension and a TypeScript rendering engine — that are combined at build time. This guide walks you through installing the required tools, generating the Xcode project, and running the app locally. It also covers the web renderer development loop and how to debug both layers.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/xykong/flux-markdown/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Before you begin, make sure your machine meets the following requirements:macOS 11 or later
macOS 11 or later
The deployment target is macOS 11.0. Xcode 14 or later is recommended to ensure compatibility with the Swift concurrency model used in
PreviewViewController.Xcode
Xcode
Install Xcode from the Mac App Store or from developer.apple.com. Command Line Tools alone are not sufficient — the full Xcode installation is required for code signing and App Sandbox entitlements.
XcodeGen
XcodeGen
XcodeGen generates
FluxMarkdown.xcodeproj from project.yml. The generated project file is excluded from version control; you must run make generate before opening the project in Xcode.Node.js
Node.js
The web renderer is a Vite/TypeScript project. Node.js 18 or later is recommended. The exact version is not pinned, but
npm install will warn about engine mismatches.Set up from scratch
Verify prerequisites
Confirm that both If
xcodegen and node are available on your PATH:xcodegen is missing, install it with brew install xcodegen. If Node.js is missing, install it with brew install node.Generate the Xcode project
A single This does the following in order:
make target builds the web renderer and generates the Xcode project:- Runs
npm installandnpm run buildinsideweb-renderer/, producingweb-renderer/dist/index.html. - Reads the current version from
.version. - Runs
xcodegen generate, creatingFluxMarkdown.xcodeproj.
You must re-run
make generate whenever you add or remove source files, or after pulling changes that modify project.yml.Open in Xcode and run
Build commands reference
All top-level build tasks are defined in theMakefile. Run these from the repository root.
| Command | Description |
|---|---|
make generate | Build the web renderer and generate FluxMarkdown.xcodeproj from project.yml. Always run this after modifying project.yml or pulling changes. |
make build_renderer | Build the TypeScript renderer only (npm install && npm run build in web-renderer/). |
make app | Run make generate then build the macOS app with xcodebuild (Release configuration). |
make install | Build and install the app locally. Calls ./scripts/install.sh, which clears the QuickLook daemon cache so the new extension is picked up immediately. |
make release [major|minor|patch] | Increment the version in .version, update CHANGELOG.md, build a DMG, and create a GitHub release. |
Web renderer development workflow
The TypeScript renderer can be developed and tested independently of the Swift layer. The Vite dev server provides a fast feedback loop for renderer changes.Install dependencies
Run tests
Tests are written with Jest and must pass before committing any renderer changes:Production build
dist/index.html using vite-plugin-singlefile. This file is what Xcode packages into the app bundle.
Playground (Vite dev server)
For rapid iteration on rendering output without rebuilding the Swift app:http://localhost:5174. Edit web-renderer/src/index.ts or the CSS files and the browser will reload automatically.
The playground runs in a normal browser context, not inside
WKWebView. Calls to window.webkit.messageHandlers are no-ops in the browser, so logging via the JS bridge will be silently skipped. Use console.log during playground development and the os_log bridge in production code.Development loop for renderer + Swift
When a renderer change is ready to test inside the actual QuickLook panel:- Run
npm run buildinsideweb-renderer/. - Run
make installfrom the repository root. - Test with
qlmanage -p path/to/file.md.
Debugging
WKWebView: Safari Web Inspector
You can attach Safari’s Web Inspector to theWKWebView running inside the QuickLook extension:
- In Safari, enable Develop menu: Safari → Settings → Advanced → Show features for web developers.
- Open a QuickLook preview (press Space on a
.mdfile in Finder, or useqlmanage -p). - In Safari, go to Develop → [Your Mac] → FluxMarkdown.
- Use the Console, Sources, and Network tabs to inspect the renderer.
Swift: os_log and the JS bridge
The Swift extension usesos_log throughout PreviewViewController.swift. Messages are tagged with the subsystem com.markdownquicklook.app. To stream logs in real time:
logger message handler:
Do not rely solely on
console.log for production diagnostics. Log entries written via console.log are not captured by the macOS unified logging system and will not appear in log stream output.Checking extension registration
If QuickLook is not using the installed extension, verify that macOS has picked it up:make install (which clears the QuickLook daemon cache) and wait a few seconds before retrying.
Conventions
TDD for the renderer
Always write a Jest test before implementing renderer logic. Run
npm test before every commit to web-renderer/.Never commit .xcodeproj
FluxMarkdown.xcodeproj is generated by XcodeGen. Edit project.yml and regenerate instead.No manual build numbers
Version and build numbers are managed by
make release and the .version file. Never set them by hand.Doc-first for hard problems
Create a
docs/debug/DEBUG_*.md file before debugging a complex issue. Record findings and decisions as you go.Related pages
Architecture overview
How the Swift host and TypeScript renderer fit together.
Web renderer overview
Deep dive into the rendering pipeline and plugin system.
Renderer testing
How to write and run Jest tests for the renderer.
Release process
How to cut a new release and update Homebrew casks.