# Notelet handles the release notes sheet iOS teams keep rewriting

> Notelet is a SwiftUI package that presents versioned release notes, reads the current version from the app bundle, and records when a user has seen them. The scope is deliberately narrow and the iOS 17 floor is firm.

**mykolaharmash/notelet** — SwiftUI component for displaying rich release notes inside an app

- Repository: https://github.com/mykolaharmash/notelet
- Stars: 555 · Forks: 22
- Language: Swift
- License: MIT
- Published: 2026-09-18 · Updated: 2026-09-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/mykolaharmash-notelet

## A sheet for release notes, and nothing else

Notelet is a SwiftUI package that shows release notes inside an iOS app. That is the entire scope, and the narrowness is the point: it solves one recurring task well rather than offering a framework.

The task is familiar to anyone shipping an app. After an update you want to tell users what changed, once, without showing it again, and without building a paging interface and version tracking from scratch each time. Every team rebuilds this, and most rebuild it badly, usually by forgetting the part that remembers whether the user has already seen it.

The audience is iOS developers on SwiftUI targeting iOS 17 or later, or iPadOS 17 or later. The platform floor rules out anyone supporting older devices, and there is no cross-platform story here at all.

## Version tracking is the feature, not the sheet

The interesting behaviour is not the presentation, it is what the package does around it.

Attaching the sheet with the current version reads the app version from the bundle, specifically the short version string, matches it against your notes array, and shows the matching entry if one exists. When the user dismisses the sheet, that version is recorded as seen, so it does not appear again. That is the whole lifecycle of the feature handled without you storing anything.

The README flags the trap in this design, and it is a real one: the version read from the bundle is the value in the target's general settings, which may differ from what appears in the store listing. Notes keyed to the wrong string simply never display, and the failure is silent. That warning is worth more than several paragraphs of API documentation, because it describes the exact way a correct integration still shows nothing.

Presentation can also be driven manually rather than automatically, by holding the presented version in state and setting it when a button is tapped, which is how you would offer release notes from a settings screen.

## Three note types and a data model that travels

Notes are an array of per version structures, each holding a version string and a list of items, and the items come in three kinds.

A list item shows a title and rows, where each row carries an SF Symbol name, a title and a description. That covers the common summary of an update, and using system symbol names rather than bundled images keeps the package free of assets. A media item comes in an image or a video variant, each taking a URL along with a title and description, which means the heavier content is fetched rather than shipped in the binary.

Multiple items for one version are arranged as a paging view, navigable by a next button or by swiping.

The detail with the longest reach is that these types conform to Codable. Notes can therefore be loaded at runtime from a server rather than compiled into the app, which means release notes can be corrected or localised after shipping without an update. For a component about communicating changes, being able to change the communication without a release is the right capability to have.

## Installing through Swift Package Manager and the first integration

Installation has no command line step. In Xcode you open the package dependency dialog, enter the repository URL, add the package, and add the Notelet library to your app target. That is the whole setup.

Integration is a single view modifier taking the notes array and the version to present. The common case passes the current version, which makes the package read the app version from the bundle, show the matching entry if one exists, and record that version as seen when the sheet is dismissed. Presenting that way happens automatically as the view hierarchy renders, so you should see release notes on the first launch after an update and nothing on the launches after that.

Showing a specific historical version instead, which is how you would build a changelog screen in settings, uses the same modifier with the version named explicitly.

```swift
 .noteletSheet(
    notes: notes,
    version: .v("1.2.1")
)
```

A third form drives presentation from state rather than automatically, by holding a presented version in a state property and assigning it when a button is tapped. The 1.2.0 release added an optional configuration argument controlling sheet height, contributed from outside the project. One modifier with a handful of call shapes is a small enough surface to learn in a sitting.

## What it will not do for you

The limits follow from the scope and are worth stating plainly.

The iOS 17 floor is the first and it is absolute. Teams supporting older versions cannot use this, and there is no fallback path documented.

The second is that this is presentation, not authoring. You maintain the notes array by hand, keyed to version strings that must match the bundle exactly, and nothing validates that a shipped version has notes. A release where someone forgets to add an entry produces no sheet and no warning, which is the correct behaviour and also means the failure is invisible until someone notices.

The third is content hosting. Image and video items take URLs, so anything richer than a symbol and text means hosting media somewhere with the availability of your app's launch path. The README does not document behaviour when that fetch fails, which is the question worth asking before using media items on a launch sheet.

There is also a promotional note in the README pointing at a separate commercial product from the same author. It is disclosed rather than hidden, and readers should simply know it is there.

## Writing the sheet yourself is the real alternative

For a component this small, the honest comparison is not another package. It is the version of this you would write in an afternoon.

A hand-rolled sheet is perhaps a hundred lines: a model for your notes, a paged view, and a stored flag recording the last version seen. You own it completely, it has no external dependency, it matches your design system exactly, and it supports whatever platform floor you already target. That last point defeats the package outright for anyone below iOS 17.

What you take on is the maintenance and the details that are easy to get wrong the first time: reading the correct bundle key, marking seen only on dismissal rather than on appearance, laying out video and image items so short text does not misalign, and keeping up with platform changes in sheet presentation. The 1.2.0 release is a good illustration, since it fixed exactly that text alignment case and added an explicit scroll edge effect for a newer iOS version.

Take the package if release notes are a recurring obligation and you would rather not revisit those details each year. Write it yourself if you need one sheet, have a strong design system, or support older devices.

## Maintenance signals and licence

Notelet is MIT licensed, which for a small user interface component is the expected and unobtrusive choice, imposing little beyond attribution.

Two releases are visible: 1.1.0 on 2026-05-17 and 1.2.0 on 2026-09-02, with the last push on the same day as the latter. Both release notes credit outside contributors by name, which for a package this size indicates people are using it enough to send fixes back.

The repository itself is as small as the scope implies: a package manifest, a sources directory and an assets directory. There is no test directory visible in the tree, which is worth weighing for a component whose most important behaviour, recording that a version has been seen, is stateful and easy to regress. Upgrade cost should be low given the single modifier surface, and the 1.2.0 addition of a configuration parameter was made as an optional argument rather than a breaking change.

## Conclusion

Notelet is worth adopting if you ship iOS 17 or later, publish release notes regularly, and would rather not maintain the version tracking and paging yourself each year. Write your own sheet instead if you support anything below iOS 17, need it to match a strict design system, or only need this once. Before integrating, confirm that the version strings in your notes array match the short version string in your target's settings rather than the number in App Store Connect, because a mismatch shows nothing at all and reports no error.

## FAQ

### What iOS version does Notelet require?

The package targets iOS 17.0 or later and iPadOS 17.0 or later. There is no documented fallback for earlier versions, so teams supporting older devices cannot use it.

### How does Notelet know whether a user has already seen the release notes?

When you present with the current version, it reads the app version from the bundle's short version string and marks that version as seen once the sheet is dismissed, so the same notes are not shown again.

### Can Notelet load release notes from a server?

Yes. The README notes that the version notes types and their nested types conform to Codable, so the notes can be loaded remotely at runtime rather than compiled into the app.

### What kinds of content can a Notelet sheet show?

Three item types are supported: a list showing rows with an SF Symbol, title and description, and media items in image or video form that take a URL plus a title and description. Multiple items for one version are shown as a paging view.

## Sources

- [Issues](https://github.com/mykolaharmash/notelet/issues)
- [License: MIT](https://github.com/mykolaharmash/notelet/blob/main/LICENSE)
- [mykolaharmash/notelet on GitHub](https://github.com/mykolaharmash/notelet)
- [README](https://github.com/mykolaharmash/notelet/blob/main/README.md)
- [Releases](https://github.com/mykolaharmash/notelet/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mykolaharmash-notelet
