A local-only alternative to CleanShot X. Everything happens on your machine. No cloud, no accounts, no network except checking for updates, which you can turn off — even captions are transcribed on your Mac.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A native macOS (Swift / SwiftUI, macOS 14+) screenshot and screen-recording app — a local-only alternative to CleanShot X: capture → annotate → copy / save / pin, and record → edit in the Studio → export.
Everything happens on your machine. No cloud, no accounts, no network except checking for updates, which you can turn off — even captions are transcribed on your Mac.查看完整 README ↗A native macOS (Swift / SwiftUI, macOS 14+) screenshot and screen-recording app — a local-only alternative to CleanShot X: capture → annotate → copy / save / pin, and record → edit in the Studio → export.
Everything happens on your machine. No cloud, no accounts, no network except checking for updates, which you can turn off — even captions are transcribed on your Mac.
Screenshots
blackout (secure, erases pixels), plus blur / pixelate (obscure only — not safe for secrets).Screen recording
Studio editor — every recording stays editable after the take
Everything else
The full contracts live in specs/; per-version highlights are in docs/releases/.
Requirements: a Mac running macOS 14 (Sonoma) or later, Apple Silicon or Intel.
There are two ways to install Lightshot:
main, or the Releases page has no download yet.Download Lightshot-<version>.dmg from the latest release (under Assets).
Install. Open the DMG and drag Lightshot into Applications. Eject the DMG afterwards. Always run Lightshot from Applications, not from the DMG or your Downloads folder — otherwise macOS runs it from a temporary location, which breaks launch-at-login and confuses the permission entry.
Get past the first-launch warning. Lightshot is open source and not notarized by Apple (that requires a paid developer account), so macOS blocks the first launch with "Apple could not verify…". This is expected. Allow it once:
macOS 15 (Sequoia) or later: open Lightshot and dismiss the warning with Done. Go to System Settings → Privacy & Security, scroll down to the message about Lightshot, click Open Anyway, and confirm.
macOS 14 (Sonoma): in Applications, right-click (or Control-click) Lightshot → Open, then click Open in the dialog.
Or, on any version, in Terminal:
xattr -dr com.apple.quarantine /Applications/Lightshot.app
Grant Screen Recording when the app asks.
Verify your download (optional). Each release's notes include a SHA-256 checksum. Compare it with your file's:
shasum -a 256 ~/Downloads/Lightshot-*.dmg
Takes a few minutes and needs no Apple Developer account.
Get the tools. Install Xcode (with Swift 6) from the Mac App Store and open it once to finish setup, then install XcodeGen with Homebrew:
brew install xcodegen
Build the app and wait for ** BUILD SUCCEEDED **:
git clone https://github.com/lethanhvietctt5/lightshot.git
cd lightshot
xcodegen generate
xcodebuild -project Lightshot.xcodeproj -scheme Lightshot -configuration Release \
-destination 'platform=macOS' -derivedDataPath build build
Move it to Applications and launch. Because you built it on your own Mac, there is no first-launch warning:
cp -R build/Build/Products/Release/Lightshot.app /Applications/
open /Applications/Lightshot.app
Grant Screen Recording when the app asks.
Lightshot is a menu-bar app — it has no main window, and appears in the Dock only while the editor is open. Look for its icon in the menu bar.
On first launch, follow the in-app onboarding to allow Screen Recording in System Settings → Privacy & Security → Screen & System Audio Recording (named Screen Recording on macOS 14), then relaunch Lightshot if macOS asks. Without it captures come back black or empty.
Other permissions are optional and requested only when you first use the feature that needs them: Microphone and Camera for recordings, Input Monitoring for the keystroke overlay, and Speech Recognition for captions (always on-device).
Lightshot updates itself. On its second launch it asks whether to check for updates automatically (about once a day); you can also choose Check for Updates… from its menu-bar menu at any time, and change either in Settings → General → Updates. An update downloads, is checked against the maintainer's signature, replaces the app in place and relaunches it, keeping your permissions and without the first-launch warning. The check is Lightshot's only network access: it fetches the release feed from GitHub and nothing about you or your captures (ADR 0002).
To update by hand, choose Quit Lightshot from its menu-bar menu, then:
Release download: download the new DMG and drag Lightshot into Applications again, choosing Replace. The first-launch warning appears once more for each new download. Versions 0.6.0 and earlier have no updater, so they update this way once.
Source build: git pull, repeat the xcodegen generate and xcodebuild commands above, then replace the installed copy:
rm -rf /Applications/Lightshot.app
cp -R build/Build/Products/Release/Lightshot.app /Applications/
If captures come back black or empty after an update, macOS has lost the Screen Recording grant even though System Settings still shows the toggle as on. Run
tccutil reset All dev.lightshot.app, relaunch, and grant the permission again. Source builds hit this on every rebuild unless you set up local code signing once (a free Apple ID is enough).
Quit Lightshot, then remove the app and its permission entries:
rm -rf /Applications/Lightshot.app
tccutil reset All dev.lightshot.app
Everything interesting is a pure function over a value type; everything OS-facing hides behind a protocol. The app depends on the package, never the reverse.
LightshotKit/ — the SwiftPM domain core. Pure Swift, no AppKit / ScreenCaptureKit imports, so it tests fast and screen-free. It holds:
AnnotationDocument — a value type mutated only through a command API (add, select, transform, setStyle, updateText, delete, reorder, applyCrop, undo, redo). Owns undo/redo history, step-number auto-increment, crop math, and hit-testing. Geometry is stored in image pixel coordinates.render(document) -> image — a pure, deterministic flatten of base image + elements, respecting crop and z-order.StudioDocument — the Studio editor's value type: timeline clips, zoom regions, captions, and canvas settings behind the same command-and-undo style, plus the pure models it draws on (ZoomCamera, CursorPath, CanvasLayout, StudioTimeline, GIFFramePlan).RecordingSession, HistoryStore, AppCoordinator, ThemePalette, and the service protocols (CaptureService, RecordingService, ImageSource, ImageSink, MediaSink, HotkeyService, AudioInputService, CameraService, InputEventSource, OverlayController, SettingsStore, …).App/ — the SwiftUI / AppKit menu-bar app shell (LSUIElement) plus the concrete ScreenCaptureKit / AVFoundation / AppKit implementations of those protocols, including the Studio compositor and exporter.scripts/ — release.sh, which builds, signs, and packages a release DMG. See .For contributors — if you just want to use the app, see Install.
Prerequisites: macOS 14+, Xcode with Swift 6, and XcodeGen:
brew install xcodegen
cd LightshotKit
swift build
swift test
swift test --filter CropTests # one suite
swift test --filter AddSelectDeleteTests/addDoesNotChangeSelection # one test
# Regenerate the (gitignored) project from project.yml first:
xcodegen generate
xcodebuild -project Lightshot.xcodeproj -scheme Lightshot -destination 'platform=macOS' build
xcodebuild -project Lightshot.xcodeproj -scheme Lightshot -destination 'platform=macOS' test
The committed default builds unsigned (App/Config/Signing.xcconfig), so CI and fresh clones need no certificate. The catch: an unsigned build gets a new code identity on every rebuild, so macOS forgets Screen Recording (and every other granted permission) each time — while System Settings still shows the stale toggle as on.
To fix it, sign with your own stable identity via a gitignored override:
In Xcode → Settings → Accounts, add your Apple ID (a free one works), then Manage Certificates → + → Apple Development.
Find your team ID — it is the certificate's OU field, not the code in parentheses in the certificate name:
security find-certificate -a -c "Apple Development" -p | openssl x509 -noout -subject
# subject=UID=…, CN=Apple Development: [email protected] (NOT-THIS-ONE), OU=ABCDE12345, …
Create App/Config/Local.xcconfig:
CODE_SIGNING_ALLOWED = YES
CODE_SIGNING_REQUIRED = YES
CODE_SIGN_STYLE = Automatic
DEVELOPMENT_TEAM = ABCDE12345
Regenerate, rebuild, and clear the grants left over from unsigned builds (one time), then grant the permissions once more:
xcodegen generate
xcodebuild -project Lightshot.xcodeproj -scheme Lightshot -destination 'platform=macOS' build
tccutil reset All dev.lightshot.app
Verify with codesign -dr - <path-to>/Lightshot.app — the designated requirement should name your certificate rather than a cdhash.
Don't set CODE_SIGN* keys in project.yml: target build settings there override the xcconfig. If you use Conductor, .conductor/settings.toml copies Local.xcconfig from your main checkout into each new workspace, so create it there.
This project is spec-driven and issue-tracked. Read AGENTS.md first — it is the single source of truth for the working agreement.
specs/NNNN-*.md and as a Linear issue (team Lightshot) — keep the two in sync.ready-for-agent label.main, using Linear's suggested branch name.main, titled <type>(LIG-<n>): <title> (e.g. feat(LIG-100): add scrolling capture).swift test, plus the app build for app-side work) before merging.blackout is safe for secrets.CGWindowListCreateImage.Lightshot is free and open source. If it saves you time, you can buy me a coffee ☕
scripts/README.mdwebsite/ — the landing page, a React + Vite site deployed on Vercel. See website/README.md.project.yml — the XcodeGen spec. Lightshot.xcodeproj is generated, not committed — run xcodegen generate after cloning or after editing project.yml.