Scrabbdict is an iOS dictionary helper for word games. It can validate a word, find words that can be built from a set of tiles, and search dictionaries with a simple ? wildcard pattern.
The app is written in Swift and SwiftUI. State management uses The Composable Architecture, and analytics/crash reporting use Firebase.
© 2013-2026 Piotr Sochalewski
Scrabbdict is an independent, non-commercial hobby project. The developer does not derive profit from the application and has no affiliation, association, authorization, sponsorship, or endorsement from Hasbro, Mattel, NASPA Word List, Collins Coalition, Éditions Larousse, Polska Federacja Scrabble, Wydawnictwo Naukowe PWN or any other owner or publisher of the referenced word lists, trademarks, or related intellectual property.
All trademarks, service marks, trade names, word list names, and other protected designations referenced in or in connection with this application are the property of their respective owners. Their use is for identification and compatibility purposes only and does not imply any relationship with, or endorsement by, the respective owners.
The project source code is licensed under the Apache License, Version 2.0. See LICENSE.
The word list archives under DAWGWizard/Files/*.zip may be subject to separate licenses, terms, or permissions from their respective sources. Those word lists are not automatically covered by Apache-2.0 unless explicitly stated by the applicable source or license. Generated dictionary data derived from those word lists, including Scrabbdict/Files/DAWG/*.dawg, may be subject to the same separate terms. See NOTICE.
The maintainer may continue to sign and publish the official App Store version independently. The app name, icon, App Store listing, bundle identifier, and backend configuration are not covered by the open source license.
Scrabbdict/- the iOS app target.Scrabbdict/Features/- SwiftUI views and TCA reducers.Scrabbdict/Helpers/- dictionary loading, validation, analytics, Crashlytics, and local storage clients.Scrabbdict/Models/- app domain models such asLanguage,Word, andSearchMode.Scrabbdict/Files/DAWG/- generated binary dictionary files used by the app.Scrabbdict/Settings.bundle/- iOS Settings app metadata, legal notice, and third-party notices.DAWGWizard/- command-line generator that converts zipped.txtword lists into compact.dawgfiles.DAWGWizard/Files/- source word list archives.ScrabbdictTests/- unit and feature tests.images/Scrabbdict.butterkit/- App Store screenshot project and exported PNG assets.Scripts/dawg- helper script that builds and runsDAWGWizard.Scripts/swiftformat-lint.sh- Xcode build phase script that checks Swift formatting.Makefileand.mise.toml- local development tooling setup.
- macOS with Xcode installed.
- iOS 17.0 or newer deployment target.
- Swift Package Manager support through Xcode.
- A Firebase iOS app configuration file named
GoogleService-Info.plist. - Local development tools managed by mise: SwiftFormat and
git-format-staged.
Xcode resolves the Swift Package Manager dependencies from Scrabbdict.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved.
The Xcode project includes a SwiftFormat Lint build phase. Run the project setup once before building locally:
make initThat installs or verifies mise, installs the tools pinned in .mise.toml, and installs a pre-commit hook that formats staged Swift files.
Useful commands:
make format
make format-lintApp Store screenshots are maintained with ButterKit. The editable ButterKit project and exported PNG assets live under:
images/Scrabbdict.butterkit/
The exported screenshots are part of the repository assets and should be regenerated from the ButterKit project when App Store presentation copy, device frames, or screenshot content changes.
The app imports Firebase Analytics and Crashlytics. To build your own copy, you must provide your own Firebase configuration:
-
Create or open a Firebase project.
-
Add an iOS app in Firebase using the bundle identifier you intend to build with. The checked-in project currently uses
pl.sochalewski.Scrabbdict. -
Download
GoogleService-Info.plist. -
Place it at:
Scrabbdict/GoogleService-Info.plist
For public forks, do not commit production Firebase credentials or service configuration unless you intentionally want that Firebase project to be used by other builds. A common approach is to keep a local GoogleService-Info.plist and commit a sanitized example file instead.
- Clone the repository.
- Run
make init. - Add your own
Scrabbdict/GoogleService-Info.plist. - Open
Scrabbdict.xcodeprojin Xcode. - Let Xcode resolve packages.
- Select the
Scrabbdictscheme. - Select an iOS simulator or a signing-capable device.
- Build and run from Xcode.
If you use a different Apple developer team or bundle identifier, update the target signing settings in Xcode before building for a device.
Open the project in Xcode, select the Scrabbdict scheme, and run the test action. The active test plan includes unit tests, feature reducer tests, and snapshot tests. Performance tests are kept in the plan but skipped by default.
The test plan is stored at:
ScrabbdictTests/Scrabbdict.xctestplan
Snapshot references are stored under:
ScrabbdictTests/__Snapshots__/
Scrabbdict does not search raw text files at runtime. Instead, each word list is compiled into a DAWG: a Directed Acyclic Word Graph. A DAWG is similar to a trie, but equivalent suffix subgraphs are merged, so common endings are stored once instead of repeated for many words.
The generator in DAWGWizard/ works broadly like this:
- Read a UTF-8
.txtword list from a.ziparchive, one word per line. - Sort the words.
- Insert each word into an incremental graph builder.
- Minimize completed branches by reusing previously seen equivalent nodes.
- Write a compact little-endian binary file with:
- a header containing magic/version/counts,
- a node table,
- an edge table.
The app loads these generated .dawg files with memory-mapped Data when possible. Validation walks graph edges for an exact word. Tile search performs a depth-first traversal while consuming available letters. Pattern search treats ? as a single-character wildcard.
The binary format is defined in DAWGWizard/DAWGBuilder.swift and read by Scrabbdict/Helpers/DAWG.swift.
Use the helper script from the repository root:
Scripts/dawgThat compiles DAWGWizard with xcrun swiftc and writes generated dictionaries to:
Scrabbdict/Files/DAWG/
Generate only selected languages:
Scripts/dawg pl_OSPS
Scripts/dawg en_US_nwl fr_ODSUse custom input or output directories:
Scripts/dawg --input-dir /path/to/word-lists --output-dir /tmp/dawgInput files are matched by language/file stem. For example, pl_OSPS expects:
DAWGWizard/Files/pl_OSPS.zip
and produces:
Scrabbdict/Files/DAWG/pl_OSPS.dawg
Each archive should contain a UTF-8 text file with the same stem, such as pl_OSPS.txt inside pl_OSPS.zip. Plain .txt files are still supported for local/custom input directories, but committed word lists should stay zipped and tracked by Git LFS.
Before redistributing regenerated dictionaries, verify the license and redistribution terms for the source word lists.
The app currently references these language identifiers:
en_GB_csw- Collins Scrabble Words (CSW, formerly SOWPODS).en_US_nwl- NASPA Word List (NWL, formerly OTCWL).fr_ODS- French ODS-style word list.pl_OSPS- Polish OSPS-style word list.
Names, descriptions, and language-specific behavior are defined in Scrabbdict/Models/Language.swift.
User-visible translations are maintained in:
Scrabbdict/Localizable.xcstrings
Keep locale-specific wording in the string catalog, but keep dictionary metadata that must stay identical across translations in code. In particular, dictionary word counts are defined as numeric values in Scrabbdict/Models/Language.swift and are injected into localized strings after locale-aware number formatting. Do not duplicate formatted word counts manually in each translation.
When updating dictionary names or descriptions, update all supported locales together (en, fr, and pl) and keep protected dictionary names, abbreviations, trademarks, and source names unchanged unless the underlying dictionary source changes. The string catalog comments mark terms that should not be translated.
User-visible third-party notices are maintained in:
Scrabbdict/Settings.bundle/Root.plist
When Swift Package Manager dependencies used by the app at runtime change, update that file to match Package.resolved. Test-only dependencies, such as snapshot testing tools, do not need to appear in the user-visible Settings bundle unless they become part of the shipped app.
- Keep generated
.dawgfiles in sync with their source.zipword list archives when changing dictionary data. - Keep legal notices and third-party notices current when changing dependencies, word lists, assets, or app branding.
- Prefix commit messages with
[AI]when the commit mainly contains AI-generated code, for example[AI] Optimize DAWG performance. - Do not commit personal signing credentials, provisioning profiles, private API keys, or production service configuration for forks.



