base on Excalidraw app for mac. Powered by pure SwiftUI. <div align="center" style="display:flex;flex-direction:column;">
<a href="https://excalidraw.com">
<img src="./ExcalidrawZ/Assets.xcassets/AppIcon.appiconset/
[email protected]?raw=true" alt="ExcalidrawZ logo" />
</a>
<h3>Excalidraw app for mac. Powered by pure SwiftUI.</h3>
</div>
 [](https://twitter.com/dove_zachary) 
<a href="https://www.chocoford.com/donation" target="_blank"><img src="https://github.com/chocoford/chocoford/blob/main/public/Donation%20Button.png?raw=true" alt="Donation to Chocoford" style="height: 60px !important;"></a>
[Excalidraw](https://github.com/excalidraw/excalidraw) is a very useful web app, but the lack of file management can be troublesome and unsettling. We often need to manually save and maintain multiple different Excalidraw files. Therefore, ExcalidrawZ has wrapped it up to automatically save edited files for users and added file grouping functionality. In future versions, iCloud automatic backup will also be added to greatly reduce the insecurity of using a web app.
## Download
[](https://apps.apple.com/app/excalidrawz/id6636493997)
**Non-App Store version (Not Recommended)**
1. Download the latest image file (.dmg) from [Releases](https://github.com/chocoford/ExcalidrawZ/releases)
2. Click the `.dmg` to install it
## Preview

## Features
#### create groups to store excalidraw files
By using the `Create folder` button located in the bottom left corner of the app, you can create new folders to organize your work.
- [x] Database groups
- [x] Customize file sort
- [x] Local Folders
- [x] Temporary files (Directly open an `.excalidraw` file)
#### Collaboration
ExcalidrawZ also supports collaboration.

#### `.excalidraw` file import
You can import any file ending with excalidraw into the app through the menu bar.
#### Share
Sharing allows you to make your work output more seamless. ExcalidrawZ supports sharing your work with others through the clipboard, file system, and system sharing menu. Additionally, ExcalidrawZ provides backup for all your files through archiving.
* export image
* export file
* export to PDF Lossless
* archive all files

#### History
Safety is a feature that ExcalidrawZ highly prioritize as a local client. To ensure this, ExcalidrawZ performs a checkpoint record of the file before you loading another file. You can tap the button on the top right of app to view the history.

#### Multiple excalidraw file format support
ExcalidrawZ now support editing of `.excalidraw`, `.excalidraw.png`, and `.excalidraw.svg` files (directly in the file system), as well as importing them into the main program.
https://github.com/user-attachments/assets/486f13c4-e0ce-4e59-a21d-bc6be5d91a81
ExcalidrawZ also supports maintaining editability when exporting images. The image files will end with `.excalidraw.png` or `.excalidraw.svg`, and ExcalidrawZ will be able to edit these types of files directly.
https://github.com/user-attachments/assets/09323b30-29f0-4522-8190-46f7ef6a9dd3
#### iOS & iPadOS support
ExcalidrawZ for iOS&iPadOS is now available. All data are synchronised by iCloud.
- Apple pencil interaction support.
- Tap with two fingers to undo.
- Tap with three fingers to redo.
## RoadMap
- [x] iCloud synchronization
- [x] iOS support.
- [ ] Support deep links.
## Contact me
Welcome to my [Discord server](https://discord.gg/aCv6w4HxDg) to share suggestions or report issues for ExcalidrawZ, helping make ExcalidrawZ even better!
## Development Guide
* The `excalidraw` core for `ExcalidrawZ` is also open-source. You can find it [here](https://github.com/chocoford/excalidraw/tree/ExcalidrawZ-core) and build for your own purposes.
* And don't forget to give it a star 😁.
* Before you start coding, don't forget to add your own `Overrides.xcconfig` in `ExcalidrawZ/Config` and populate it with the following content:
```xcconfig
DEVELOPMENT_TEAM = <YOUR_DEVELOPMENT_TEAM_FOR_DEBUG>;
ICLOUD_CONTAINER = <YOUR_ICLOUD_CONTAINER_IDNENTIFIER_FOR_DEBUG>;
```
", Assign "at most 3 tags" to the expected json: {"id":"13591","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"