Appkit without storyboards XCode 26.2

I’m running macOS 15.7 with Xcode 26.2, and I’m trying to learn the basics of AppKit.

I’m fully aware that AppKit is considered a legacy / “old” technology and that Apple clearly does not promote it out of the box anymore. This is especially visible in recent versions of Xcode, where you can no longer create a macOS App template without Storyboards or SwiftUI. That said, AppKit is still widely used under the hood, so I think it’s reasonable to at least understand its fundamentals.

Here’s the problem I’m facing.

I create a standard macOS App project using the Xcode template (AppKit App Delegate). Then I:

delete Main.storyboard

remove all storyboard references from Info.plist

try to create the window manually in applicationDidFinishLaunching

At this point, the project builds, but the app either:

does not show any window, or

behaves as if it were not a proper GUI app

While debugging, it looks like Xcode / Swift is treating my target more like a dylib / wrapper than a normal .app bundle (at least judging by runtime behavior and the lack of a proper AppKit lifecycle).

While searching for answers, I found this article: https://ashidiqi.com/blog/how-to-setup-xcode-project-programmatically-with-appkit/

The author claims that in this scenario you must not use the @main attribute and instead need a main.swift file that manually calls NSApplicationMain.

However, the article also mentions that Xcode shows the error:

'main' attribute cannot be used in a module that contains top-level code

The confusing part is that I do not have any top-level code in my project when using @main.

At the same time, when I ask an LLM for clarification, it tells me that:

@main does not require a storyboard

removing a storyboard does not force you to switch to main.swift

@main should work fine for a fully programmatic AppKit app

So I’m left with two concrete questions:

  1. What is the correct, modern answer here? When building a fully programmatic AppKit app (no storyboard, no SwiftUI), do you actually need main.swift, or is @main still fully supported and correct?

  2. Is there any supported or recommended way in modern Xcode to get a “clean” AppKit app template without a storyboard? Either via project settings, templates, or some documented workflow — without having to fight the build system or end up with a half-broken target.

I’m not trying to fight Apple’s direction here — I just want to understand the correct way to work with AppKit in 2025, even if it’s not the preferred path anymore.

Thanks in advance for any clarification.

Thanks for the post, very interesting and got a few questions reading your post mainly instead of answers, I’ll invite other developers for their opinion as I’m mainly in SwiftUI, but your post is interesting and intriguing to me.

What the motivation of creating a macOS AppKit app without using Storyboards or SwiftUI. How are you planning to do with the UI/UX?

Yes, even though the shift is more towards SwiftUI and other modern frameworks. However, the @main attribute can be tricky when used in conjunction with AppKit, especially when you want to manually set up your application lifecycle?

Are you talking about his?

import Cocoa

@main
class AppDelegate: NSObject, NSApplicationDelegate {
    var window: NSWindow?

    }

Trying to understand what you are trying to accomplish and your goals on the project. Looking forward to your answer!

Albert Pascual
  Worldwide Developer Relations.

@hieronim-bosch AppKit is my favorite framework, nothing else comes close. Until proven otherwise there is still no better way to make a Mac app IMHO.

That said I never got into Storyboards on Mac. In Xcode 26.2 I can still create an AppKit project the "old way" which is New Project -> macOS -> App then change Interface to XIB then you get a project without a storyboard.

If you want to go completely without Interface Builder you can but I don't think Apple ever had a template for that setup (well if they did I never noticed or it must have been a really long time ago).

You can set the NSApplication delegate in main.


#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (strong) NSWindowController *mainWindowController;

@end

@implementation AppDelegate

-(void)applicationDidFinishLaunching:(NSNotification*)aNotification
{
	NSLog(@"Hello world!");
	NSWindow *firstWindow = [[NSWindow alloc]initWithContentRect:NSMakeRect(50.0, 50.0, 400.0, 400.0) styleMask:NSWindowStyleMaskTitled backing:NSBackingStoreBuffered defer:NO];
	firstWindow.title = @"Xibless";
	self.mainWindowController = [[NSWindowController alloc]initWithWindow:firstWindow];
	[self.mainWindowController showWindow:nil];
}

@end

// main.m
int main(int argc, const char * argv[]) {
	@autoreleasepool {
		NSApplication *app = [NSApplication sharedApplication];
		AppDelegate *appDelegate = [[AppDelegate alloc]init];
		app.delegate = appDelegate;
		[app setActivationPolicy:NSApplicationActivationPolicyRegular];
		[app run];
	}
}

and I think you also need to build the menu bar programmatically. IMO there really is no reason to do all this. If you want to avoid Interface Builder I think it's more reasonable to just do the following:

  1. Create an Xib project.
  2. Keep the MainMenu.xib but inside it delete the window but leave the menu bar.

Then in your AppDelegate just make your NSWindowController / NSWIndow in code. Then you're mostly without IB - enough for learning.

Or if you want you can build the menu bar (see mainMenu property on NSApplication: https://developer.apple.com/documentation/appkit/nsapplication/mainmenu?language=objc).

Appkit without storyboards XCode 26.2
 
 
Q