🛠️ Building Hammer for Mac: technical thread

As I rebuild Hammer for Mac from scratch, I’m excited to take a build-in-public approach to share the technical side of the journey. This thread will be where I post thoughts, ideas, and code snippets as I navigate the challenges of creating a modern, Swift-based version of Hammer for 2025.

A few things I’ll dive into here:

  • The shift from Ruby-based engines to an all-native Swift build pipeline.
  • Reimagining the Hammer tag system for modern HTML, CSS, and JavaScript workflows.
  • How I’m leveraging SwiftUI for the app’s sleek, native Mac interface.
  • Experimenting with generative AI to simplify front-end tasks while keeping Hammer intuitive and GUI-first.

I’ll also be sharing problems I encounter, solutions I explore, and questions I have along the way. Whether you’re a developer interested in Hammer or just curious about the process, I’d love for you to join the conversation!

Let’s geek out together. Feel free to share ideas, feedback, or questions as I build Hammer for the next generation of front-end developers.

Cheers,
Steve

Thought I’d kick off with a bit of an overview of some of the core technical considerations (that come to mind) which I’ve tackled in some way so far.

Hammer Swift Project Overview

Architecture Overview

Core Components

  1. Compiler System

    • [IMPLEMENTED] Build Process Management: Orchestrates the entire build pipeline
    • [IMPLEMENTED] File Processing Pipeline: Handles file parsing and transformation
    • [IMPLEMENTED] Caching System: Intelligent caching mechanism
    • [PARTIALLY IMPLEMENTED] Asset Compilation: Processes and optimizes various asset types
    • [IMPLEMENTED] Tag Processing: Custom tag parsing and transformation system
  2. Frontend Application

    • [IMPLEMENTED] Native macOS SwiftUI Interface: Modern, responsive UI

      • AddProjectView ✓
      • AddSiteSheet ✓
      • AddSiteView ✓
      • ProjectListView ✓
      • SiteDetailView ✓
      • SiteListView ✓
      • SiteSettingsView ✓
      • TemplateGalleryView ✓
      • WelcomeView ✓
    • [IMPLEMENTED] MVVM Architecture: Clean separation of concerns

      • Views properly separated ✓
      • ProjectStore ViewModel with clear responsibilities ✓
      • State management through ObservableObject ✓
    • State Management:

      • [IMPLEMENTED] Robust state handling using Combine framework
        • @Published properties ✓
        • ObservableObject conformance ✓
        • State propagation ✓
      • [IMPLEMENTED] SwiftUI state primitives integration
        • @State for local state ✓
        • @Binding for state passing ✓
        • @EnvironmentObject for dependency injection ✓
    • [IMPLEMENTED] Developer-Centric UX: Streamlined workflows

      • Drag and drop support ✓
      • Keyboard shortcuts ✓
      • Context menus ✓
      • Progress indicators ✓
      • Error handling ✓
    • [IN PROGRESS] Accessibility Support:

      • Basic VoiceOver support through SwiftUI

      • Custom accessibility labels needed

      • Keyboard navigation improvements needed

      • [IN PROGRESS] Text Editor Integration:

        • Select preferred text editor ✓
        • Open files in editor ✓
        • [IMPLEMENTED] Sublime Text ✓
        • [IN PROGRESS] VSCode
        • [IN PROGRESS] Cursor
  3. Other Components

    • [IMPLEMENTED] CLI Tools: Command-line interface for testing and debugging

      • HammerCLI ✓
      • BuildTester ✓
      • PerformanceProfiling ✓
    • [IMPLEMENTED] Sample Projects: Test cases and examples

      • BasicBlog ✓
      • ComplexLayout ✓
      • CustomTags ✓
      • NestedIncludes ✓
    • [IMPLEMENTED] Template System:

      • Default templates ✓
      • Custom template creation ✓
      • Create from Template flow ✓
    • [IMPLEMENTED] Forge Integration:

      • Basic publishing workflow ✓
      • Authentication setup ✓
      1. Data Model
    • [IMPLEMENTED] Project Management:

    • Project creation ✓

    • Project deletion ✓

    • Project settings

    • Project templates

    • [IMPLEMENTED] Site Management:

    • Site creation ✓

    • Site deletion ✓

    • Site settings ✓

    • Site templates ✓

    • [IN PROGRESS] Site Settings:

    • Cache toggle ✓

    • Forge site selection ✓

Let me know if you want to discuss any particular concept or area, but I’ll share more about these areas as we go…

hammer-projects

This is one of the most obvious differences from OG Hammer - the introduction of Projects as an organising structure.

At peak usage, I had a lot of sites in my Hammer app, it became unwieldy. I had the same issue in Forge. In the NEW Forge app, we’ve introduced Projects and I want consistency / parity in the domain model between our products. So we have Projects. A Project has many Sites.

I’ve got so much to update relating to stuff I’ve already worked on the past couple of weeks, so I’ll not do that right now and just provide an update on what I’ve achieved today :sweat_smile:

  1. Finally resolved opening sites in Cursor and VS Code which had been bothering me. Tried all sorts of ways, including exactly the same way we did it in og Hammer (which still works, as it goes). Like shopping with my wife, went through all sorts of approaches including CLI and Applescript and eventually came back to the app url scheme like vscode://file/{{path-to-folder}} which I tried first but didn’t work initially.

  2. This opened up an opportunity to do what I really had been wanting to do in Cursor.cursorrules injection when selecting Cursor as the preferred editor. Now, when you select Cursor and build, we will create a .cursorrules file in the root of the project with our Hammer rules to fine-tune the context of how Cursor can help you with your Hammer projects with generative AI. It’s like magic :magic_wand:

  1. :lady_beetle: Bug bashing - there were some obvious issues in the compilation process that I cleaned up: relative paths in @stylesheet and @javascript link tags.

  2. :warning: Added better errors for common situations and creating an extensible approach to adding more cases in future.

  1. Improved the UX and handling of variables used in includes where the variable was created in the parent scope. Not perfect but better…

  2. Fixed a bug where the compilation was opening asset files as text and raising an error. These are now distinguished from text files and just copied across to the Build.

  3. Added .hammer-ignore (parity to OG Hammer) for ignoring specified files. Created GUI in Site Settings for authoring hammer ignore rules. Improved Site Settings layout somewhat.

Today I’ve been fixing more bugs in the compilation process, particularly with recursive/nested includes and css tags.

But more interesting (to me at least) was that I wanted to create a PoC for a very specific use case for Hammer that fits with our new direction for Forge - Plugin Development.

I created the first of what will I hope be a number of optional utility tags to support plugin development on all the amazing platforms that are out there (and those to come).

I’ve started with Miro, the visual collaboration workspace.

The <!— @miro —> tag will unlock the magic:

  1. It will automatically add the necessary Miro SDK and Mirotone CSS files to your html page and initialise the SDK by generating a Miro specific js file that is added to your assets/js folder.
  2. It will generate a Miro test environment wrapper via a mock.html file and companion js file that will give you the option to load your plugin in a mocked UI to test it out, simulate and debug SDK requests and payloads, so you don’t have to actually run it in the Miro app, saving a lot of time during development.
  3. When/if you decide to remove the Miro tag, Hammer cleans up after you removing all the files
  4. If you’re using Cursor editor, Hammer extends your .cursorrules file with content specifically tailored to development of Miro plugins using Hammer, so you can get AI to help you write code and test faster.

Next up I’d like to explore passing arguments to the Hammer tag for more fine tuned control, especially for the setup - probably starting with specification of the extension point being used (panel, modal, background)

Back to the fundamentals… my latest version has been working really well even for some proper client sites I’ve made the past couple of days - typically small, few pages. Super fast, reliable, slick :kissing_heart:

Today I tried exporting a larger webflow export with around 300 uncached files.

It crapped out.

Not on build, that took a few seconds, but in post build file enumeration.

So today, is optimisation day….

Please include BBEdit as an editor. Thanks.

1 Like

You seem to have a lot of projects underway, but would it be possible to get at least monthly updates on HammerForMac?

1 Like

That’s just the kind of ask I’m looking for - keep me honest!

Hammer is coming along, I’ll post another update here shortly.

I’m using it actively for (mostly small) internal projects at the moment, I’ll publish a preview build for anyone that wants to participate in testing, reporting feedback and issues.

Excellent. Thank you.