

Product
Grimoire — A lightweight songwriting App
Grimoire — A lightweight songwriting App
Grimoire — A lightweight songwriting App
Tools
Figma
Cursor
Xcode
Figma
Cursor
Xcode
Figma
Cursor
Xcode
Tech Stack
SwiftUI DSwaveformImage
Lottie
SwiftUI DSwaveformImage
Lottie
SwiftUI
DSwaveformImage
Lottie
Goals
Provide songwriters with a seamless way to write song lyrics on their iPhones.
Provide songwriters with a seamless way to write song lyrics on their iPhones.
Provide songwriters with a seamless way to write song lyrics on their iPhones.
My Role
Designed in Figma and built with Cursor and Xcode. Grimoire is an iOS songwriting app that allows users to attach audio files to a notepad, loop sections of music, and organize songs into folders. This enables a seamless songwriting experience that reduces friction and supports creative flow.
Designed in Figma and built with Cursor and Xcode. Grimoire is an iOS songwriting app that allows users to attach audio files to a notepad, loop sections of music, and organize songs into folders. This enables a seamless songwriting experience that reduces friction and supports creative flow.
Designed in Figma and built with Cursor and Xcode. Grimoire is an iOS songwriting app that allows users to attach audio files to a notepad, loop sections of music, and organize songs into folders. This enables a seamless songwriting experience that reduces friction and supports creative flow.
Building with AI
Building with AI
The initial plan was to build this with React Native and CocaPods, I quickly realized that wasn't ideal an instead switch to a SwiftUI build for more control over audio playback. Together with Figma MCP and Cursor I was able to build a working prototype quickly, the app is now in the process of being deployed to the App store.
The initial plan was to build this with React Native and CocaPods, I quickly realized that wasn't ideal an instead switch to a SwiftUI build for more control over audio playback. Together with Figma MCP and Cursor I was able to build a working prototype quickly, the app is now in the process of being deployed to the App store.
The initial plan was to build this with React Native and CocaPods, I quickly realized that wasn't ideal an instead switch to a SwiftUI build for more control over audio playback.
Together with Figma MCP and Cursor I was able to build a working prototype quickly, the app is now in the process of being deployed to the App store.
Outcomes
Shipped a working beta to 12 early testers, receiving feedback on clarity and usability.
Shipped a working beta to 12 early testers, receiving feedback on clarity and usability.
Shipped a working beta to 12 early testers, receiving feedback on clarity and usability.
92% of users said looping felt “more intuitive” than their current setup.
92% of users said looping felt “more intuitive” than their current setup.
92% of users said looping felt “more intuitive” than their current setup.
Discovered an opportunity to evolve into a full song draft manager, potentially including cloud sync and version history.
Discovered an opportunity to evolve into a full song draft manager, potentially including cloud sync and version history.
Discovered an opportunity to evolve into a full song draft manager, potentially including cloud sync and version history.
Problem Space
Problem Space
When songwriting, many tools outside of pen and paper can be distracting. Many iOS users rely on the native Notepad app, but it lacks key features that would make it ideal for writing with music.
Solutions
Solutions
Import and attach audio directly to a notepad.
Import and attach audio directly to a notepad.
Loop specific audio segments for detailed lyric writing or melody matching.
Loop specific audio segments for detailed lyric writing or melody matching.
Organize songs into folders, enabling structured songwriting sessions across projects.
Organize songs into folders, enabling structured songwriting sessions across projects.
Research & Discovery
To validate the opportunity, I interviewed musicians and songwriters ranging from bedroom producers to professional artists. Key insights:

"I mainly use the native iPhone notepad because you can play music in it."

"The notepad app has an audio player but it doesn't have a looping feature to make writing hooks easier."

"Having a digital version of my song lyrics makes it easier to upload them to website like Genius."
Key Features
Key Features
🎼 Audio + Notepad
Users can attach local and cloud based audio files and playback their music while writing lyrics.
🔁 Looping Engine
Implemented custom loop points users can drag and reset, supporting precise section focus.
🗂 Folder System
Inspired by file managers, users can create folders, move songs, and collapse lists for clean navigation.
Icon
Icon
A simple but eye grabbing icon was chosen for the app, I wanted something that could be easily located when opening up your phone.
A simple but eye grabbing icon was chosen for the app, I wanted something that could be easily located when opening up your phone.

Adding a Song
Adding a Song
Users can quickly browse local and cloud based files and attach them to song sessions.
Users can quickly browse local and cloud based files and attach them to song sessions.

Music Player
Music Player
As a key touchpoint of the app I wanted the music player to be easy to use but also subtle.
Considering responsiveness I opted to simply the player from earlier version to ensure screen compatibility.
As a key touchpoint of the app I wanted the music player to be easy to use but also subtle.
Considering responsiveness I opted to simply the player from earlier version to ensure screen compatibility.


Resident Profiles
Resident Profiles
Data is key for proper resident management, this page serves as the center for internal users. I made sure to present data in a manageable way for the users.
Data is key for proper resident management, this page serves as the center for internal users. I made sure to present data in a manageable way for the users.

Design Tokens
Design Tokens
As a key touchpoint of the app I wanted the music player to be easy to use but also subtle.

Font Tokens
struct DesignTokens { // Brand color - stays consistent across themes static let brandColor = Color(red: 0.941, green: 0.408, blue: 0.220) // #F06838 // Typography - Dynamic Type support using text styles // These automatically scale with user's preferred text size static let headingFont = Font.system(.largeTitle, design: .rounded).weight(.bold) static let bodyFont = Font.system(.body, design: .rounded).weight(.regular) static let subheadingFont = Font.headline.weight(.semibold) static let songTitleFont = Font.headline.weight(.semibold) static let songSnippetFont = Font.subheadline.weight(.regular) // Additional Dynamic Type fonts for specific UI elements static let headerTitleFont = Font.system(.headline, design: .rounded).weight(.semibold) static let buttonFont = Font.body.weight(.semibold) static let captionFont = Font.caption.weight(.regular) static let footnoteFont = Font.footnote.weight(.regular) static let settingsTitleFont = Font.subheadline.weight(.semibold) static let settingsSubtitleFont = Font.footnote.weight(.regular) static let settingsSectionFont = Font.caption.weight(.medium) static let upgradeButtonFont = Font.body.weight(.semibold) static let featureTitleFont = Font.subheadline.weight(.medium) static let featureSubtitleFont = Font.subheadline.weight(.regular) static let timeDisplayFont = Font.caption.weight(.medium).monospaced() static let musicPlayerTitleFont = Font.system(.caption, design: .default).weight(.medium) static let lyricEditorFont = Font.body.weight(.regular) static let placeholderFont = Font.body.weight(.regular) static let errorFont = Font.caption2.weight(.regular) // For cases where we need custom sizing with Dynamic Type support static func customFont(style: Font.TextStyle, weight: Font.Weight = .regular, design: Font.Design = .default) -> Font { Font.system(style, design: design).weight(weight)
struct DesignTokens { // Brand color - stays consistent across themes static let brandColor = Color(red: 0.941, green: 0.408, blue: 0.220) // #F06838 // Typography - Dynamic Type support using text styles // These automatically scale with user's preferred text size static let headingFont = Font.system(.largeTitle, design: .rounded).weight(.bold) static let bodyFont = Font.system(.body, design: .rounded).weight(.regular) static let subheadingFont = Font.headline.weight(.semibold) static let songTitleFont = Font.headline.weight(.semibold) static let songSnippetFont = Font.subheadline.weight(.regular) // Additional Dynamic Type fonts for specific UI elements static let headerTitleFont = Font.system(.headline, design: .rounded).weight(.semibold) static let buttonFont = Font.body.weight(.semibold) static let captionFont = Font.caption.weight(.regular) static let footnoteFont = Font.footnote.weight(.regular) static let settingsTitleFont = Font.subheadline.weight(.semibold) static let settingsSubtitleFont = Font.footnote.weight(.regular) static let settingsSectionFont = Font.caption.weight(.medium) static let upgradeButtonFont = Font.body.weight(.semibold) static let featureTitleFont = Font.subheadline.weight(.medium) static let featureSubtitleFont = Font.subheadline.weight(.regular) static let timeDisplayFont = Font.caption.weight(.medium).monospaced() static let musicPlayerTitleFont = Font.system(.caption, design: .default).weight(.medium) static let lyricEditorFont = Font.body.weight(.regular) static let placeholderFont = Font.body.weight(.regular) static let errorFont = Font.caption2.weight(.regular) // For cases where we need custom sizing with Dynamic Type support static func customFont(style: Font.TextStyle, weight: Font.Weight = .regular, design: Font.Design = .default) -> Font { Font.system(style, design: design).weight(weight)
Looping in Action
Looping in Action
Keeping the timestamps while customizing the loop was a top ask from beta testers.
Keeping the timestamps while customizing the loop was a top ask from beta testers.

Next Steps
Launch on app store in Q3.
Launch on app store in Q3.
Launch on app store in Q3.
Build backend structure and
Build backend structure and
Build backend structure and
Expand notepad features with annotations, and maybe add social aspect if userbase allows for it.
Expand notepad features with annotations, and maybe add social aspect if userbase allows for it.
Expand notepad features with annotations, and maybe add social aspect if userbase allows for it.