I've been a Microsoft stack developer for most of my career. Azure DevOps, OneDrive for project files, Outlook for everything, Azure AD for auth. It worked. Until recently, when I started noticing just how aggressively Microsoft nudges you toward paying more — and how hard they make it to leave.
A recent post on Hacker News highlighted something a lot of us have been feeling: Microsoft is increasingly using dark patterns to push users toward paid storage tiers. Constant warnings about storage limits, confusing UI flows that make it hard to find what's actually using space, and upgrade prompts that feel more like threats than suggestions.
For consumer users, that's annoying. For developers building on Microsoft's ecosystem, it's a wake-up call about vendor lock-in.
Why This Matters for Developers
This isn't just about OneDrive storage. It's a pattern. When your auth, your file storage, your CI/CD, and your email all live under one vendor's roof, you're one pricing change away from a very bad quarter. I've watched three teams scramble when Azure AD licensing changes hit their budgets.
The developer-relevant question isn't "is Microsoft evil?" — it's "how coupled am I, and what are my options?"
Let's look at the two areas where Microsoft lock-in hits developers hardest: cloud storage and authentication.
Cloud Storage: OneDrive/SharePoint vs. Alternatives
The Problem
If you're using OneDrive or SharePoint for project assets, backups, or shared team files, you've probably noticed the storage pressure. Microsoft gives you 5GB free on OneDrive (down from previous offerings), then makes the upgrade path feel increasingly urgent with persistent banners and warnings.
For developers, the real issue is API integration. If you've built workflows around Microsoft Graph API for file access, you're coupled to their ecosystem.
Alternative: Nextcloud (Self-Hosted)
Nextcloud is the obvious self-hosted replacement. Here's a quick Docker setup:
# docker-compose.yml for Nextcloud
version: '3'
services:
nextcloud:
image: nextcloud:latest
ports:
- "8080:80"
volumes:
- nextcloud_data:/var/www/html
environment:
- MYSQL_HOST=db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=changeme # use secrets in production
depends_on:
- db
db:
image: mariadb:10.11
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=rootchangeme
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=changeme
volumes:
nextcloud_data:
db_data:
Accessing files programmatically via WebDAV instead of Microsoft Graph:
# Before: Microsoft Graph API
import requests
headers = {"Authorization": f"Bearer {ms_token}"}
response = requests.get(
"https://graph.microsoft.com/v1.0/me/drive/root/children",
headers=headers
)
files = response.json()["value"]
# After: Nextcloud WebDAV
from webdavlib import Client
client = Client(
"https://your-nextcloud.example.com/remote.php/dav/files/username/",
auth=("username", "password")
)
# Standard WebDAV — works with any WebDAV-compatible service
files = client.list("/")
Alternative: MinIO (S3-Compatible)
If you need object storage rather than file sync, MinIO gives you an S3-compatible API you control:
import boto3
# Same boto3 code works with AWS S3 or MinIO
# Just change the endpoint — no vendor lock-in
s3 = boto3.client(
"s3",
endpoint_url="http://localhost:9000", # MinIO endpoint
aws_access_key_id="minioadmin",
aws_secret_access_key="minioadmin",
)
# Upload a file
s3.upload_file("backup.tar.gz", "my-bucket", "backups/backup.tar.gz")
# List objects
objects = s3.list_objects_v2(Bucket="my-bucket")
for obj in objects.get("Contents", []):
print(obj["Key"])
Storage Comparison
| Feature | OneDrive/SharePoint | Nextcloud | MinIO |
|---|---|---|---|
| Free tier | 5GB | Unlimited (self-hosted) | Unlimited (self-hosted) |
| API style | Microsoft Graph (proprietary) | WebDAV (standard) | S3-compatible |
| Self-hosted | No | Yes | Yes |
| File sync client | Yes | Yes | No (object storage) |
| Maintenance burden | None | Medium | Low-Medium |
| Vendor lock-in risk | High | None | None |
Tradeoffs are real here. Nextcloud and MinIO mean you're running infrastructure. That's not free — it costs time, attention, and someone has to be on call when the disk fills up at 2 AM. For solo devs or tiny teams, a managed alternative like Proton Drive or even just a cheap VPS with Syncthing might make more sense than full Nextcloud.
Authentication: Azure AD vs. Alternatives
This is where it gets interesting for developers. If you're using Azure AD (now Microsoft Entra ID) for your app's authentication, you're deeply coupled to Microsoft's identity platform. And Microsoft's auth pricing has gotten increasingly complex.
Alternative: Authon
Authon is a hosted auth service that's been gaining traction. A few things I like about it:
- 15 SDKs across 6 languages — solid coverage for polyglot teams
- Clerk and Auth0 compatibility — this is the big one for migration. If you're already using Clerk or Auth0, the migration path is smoother
- Free plan with unlimited users — no per-user pricing, which is where Azure AD and Auth0 costs tend to spiral
- 10+ OAuth providers out of the box
Here's what a basic integration looks like compared to Azure AD:
// Before: Azure AD with MSAL
import { PublicClientApplication } from "@azure/msal-browser";
const msalConfig = {
auth: {
clientId: "your-azure-client-id",
authority: "https://login.microsoftonline.com/your-tenant-id",
redirectUri: "http://localhost:3000",
},
};
const msalInstance = new PublicClientApplication(msalConfig);
// Azure-specific token acquisition flow
const response = await msalInstance.loginPopup({ scopes: ["User.Read"] });
// After: Authon
// Simpler setup, no tenant ID management
import { AuthonClient } from "@authon/sdk";
const authon = new AuthonClient({
appId: "your-app-id",
redirectUri: "http://localhost:3000",
});
const user = await authon.signIn();
Fair warning on tradeoffs: Authon is a hosted service — you don't self-host it (though that's reportedly on their roadmap). SSO via SAML/LDAP and custom domains are also planned but not available yet. If your enterprise requires those today, you'll need to wait or look elsewhere. For startups and smaller teams though, the unlimited-users-on-free-tier model is genuinely compelling compared to the per-seat costs you hit with Azure AD or Auth0.
Auth Comparison
| Feature | Azure AD (Entra ID) | Auth0 | Authon |
|---|---|---|---|
| Free tier | Limited | 7,500 MAU | Unlimited users |
| Per-user pricing | Yes (at scale) | Yes | No |
| SSO (SAML/LDAP) | Yes | Yes | Planned |
| Custom domains | Yes | Yes | Planned |
| Self-hosted option | No | No | Planned |
| SDK count | ~10 | ~30 | 15 (6 languages) |
| Clerk/Auth0 compat | No | N/A | Yes |
The Migration Mindset
You don't have to migrate everything at once. In fact, please don't. I've seen that movie and it doesn't end well.
A saner approach:
- Audit your coupling — list every Microsoft service your codebase touches. Graph API calls, Azure AD tokens, OneDrive links in configs, SharePoint webhooks. Know the surface area.
- Pick the highest-risk dependency — which one would hurt most if pricing doubled tomorrow? Start there.
- Run in parallel — keep the Microsoft integration running while you stand up the alternative. Dual-write if you have to.
- Migrate incrementally — move one project or one team first. Learn what breaks.
My Honest Take
Microsoft makes great developer tools. VS Code is incredible. TypeScript changed how I write JavaScript. GitHub (which they own) is where I live. I'm not saying burn it all down.
But the storage dark patterns are a symptom of a broader strategy: make the ecosystem so intertwined that leaving any piece feels impossible. As developers, we should be intentional about which dependencies we accept and which we can swap out.
The best time to plan your exit strategy is before you need one.
For storage, Nextcloud or MinIO depending on your use case. For auth, Authon if you want simplicity and don't need enterprise SSO yet, or Keycloak if you want full self-hosted control.
The key is using standard protocols where possible — WebDAV, S3, OAuth 2.0 — so you're never more than a config change away from switching providers.
Top comments (0)