AI Didn’t Break Your Culture. It Exposed It.

An engineer pushes back on a decision. The response: “ChatGPT recommended something else.” The tell isn’t the recommendation. It’s that they reached for an oracle instead of an argument. You’re not watching an AI problem. You’re watching a culture problem that predates the model by years.

I’ve been the oracle.

The Oracle Was Always There

Before ChatGPT, it was Stack Overflow. Before Stack Overflow, it was the one senior engineer who had been around longest. Teams find oracles when they don’t have frameworks. They fill the decision vacuum with whatever authority is nearest.

ChatGPT is just the most accessible oracle ever built. It’s confident, available at 2am, and it never makes you feel stupid for asking. Of course engineers reach for it.

The question is what they’re replacing with it.

If your team has no shared framework for architectural decisions, no clear authority structure, no agreed-on method for weighing tradeoffs … “ChatGPT recommended something else” is just the latest version of “Google says” or “I read a blog post” or the last tech talk someone attended. The source changes. The abdication of thinking stays the same.

That’s the culture problem. And it was there long before the first API call.

One flavor of team gets hit hardest. The team that’s technically accomplished but has never had to articulate its reasoning under pressure. The team where the senior engineers make the calls and everyone else executes. The team where architecture reviews are about performance, not inquiry. Those teams look fine until the oracle arrives and the emperor’s new clothes problem becomes impossible to ignore.

A lot of engineering culture runs on borrowed credibility. Conference talks from FAANG engineers with entirely different constraints. Benchmarks run on workloads nothing like yours. Technical opinions absorbed as gospel without anyone stress-testing the assumptions. Teams learn to cite sources instead of building judgment. ChatGPT is the endpoint of that trajectory … a perfectly confident authority on everything, available for anything, with zero friction and no accountability for being wrong.

When a culture already runs on borrowed credibility, an always-available oracle doesn’t change behavior. It accelerates it.

What Culture Actually Does

I’ve been the oracle. Decisions on my team ran through me. The projects that worked were the ones I was close to. I read that as signal that I was adding value. It was a sign that I’d built a dependency, not a team. The engineers weren’t deferring to me because my judgment was better. They were deferring because I had never built a culture where their judgment was tested.

When ChatGPT arrived, teams like the one I used to run had an obvious replacement oracle. Different interface. Same problem underneath.

Culture is not your team values on a Confluence page. It’s not the engineering principles doc nobody reads after onboarding. It’s not the Slack channel with memes and the occasional win.

Culture is what happens when nobody’s watching. The shared understanding of how decisions get made, how tradeoffs get reasoned through, how an engineer pushes back on a bad idea without making it personal. The invisible scaffolding that holds the architecture together when you’re not in the meeting.

Principals’ dashboards looked great. Velocity up. Output up. Ask about unplanned work and the room went quiet. Nobody had a number. The dashboards measured what was easy to measure, not what was actually happening inside the codebase.

What was happening in teams where AI tooling ran without guardrails was exactly what you’d expect from a team without shared standards. Multiple HTTP client implementations pulling in different directions. Conflicting error-handling patterns across the same surface. Inconsistent approaches to the same category of problem, sometimes within the same file. Not because engineers were careless. Because there was no shared framework for what “right” looked like, and AI filled that vacuum at ten times the speed of any individual contributor.

The teams that thrived had done the work before AI arrived. Standards weren’t a reaction to the new tools. Code patterns documented. Architecture decisions written down with the “why” included, not just the outcome. When you hand those teams an AI coding assistant, it becomes a force multiplier. The output fits the system.

When you hand that same tool to a team with no shared framework, you get a junk drawer with a CI/CD pipeline.

What AI Actually Exposed

AI didn’t break your culture. It exposed teams that never built one.

Most leaders will tell you they have a culture. They’ll point to the Notion doc. The architecture review calendar. The two-week sprint cadence. That’s structure. Structure and culture are not the same thing.

Real culture is whether your engineers can defend a decision in their own words. Not quote what a tool recommended. Not point to a benchmark someone else ran. Construct the argument. Weigh the tradeoffs. Say “here’s what I considered, here’s what I chose, and here’s what I’m watching to know if I was wrong.”

If your engineers can do that, AI is a force multiplier.

If they can’t, you have a problem that predates the model.

The culture that produces “ChatGPT said so” as a decision argument is the same culture that produces decisions by committee, approval chains that substitute for judgment, and teams that stopped asking “why” because it was never welcomed in the room. AI just gave that culture a name and a quotable moment.

AI didn’t create teams that can’t think. It created a faster, more accessible oracle that made the problem visible.

Teach Them to Think

Architecture Decision Records written for the engineer who wasn’t in the room when the decision was made. Not bullet points justifying the choice after the fact … actual reasoning. Here’s what we considered. Here’s what we ruled out and why. Here’s what we’re watching to know if we got it wrong. That’s the document that builds judgment over time. ADRs written that way become the baseline for how engineers on your team actually make decisions, long before any AI model enters the picture. One ADR on session management saved us from a full migration that turned out to be unnecessary.

Code standards documented as reasoning, not rules. Here’s the choice, here’s what it costs, here’s when you should challenge it. The same standards that let an engineer recognize a bad architectural recommendation from an AI are the ones that let them recognize a bad recommendation from a colleague, or from themselves at 11pm under deadline pressure. You don’t build two separate frameworks for human decisions and AI decisions. You build one. You make it cheap to be wrong and expensive to hide it.

Review culture that interrogates “why” before it approves “what.” The mid-level engineer who asks “why are we building this?” in a planning meeting is worth more to the team than the senior who executes quietly and ships fast. That question is the signal you hire for. The engineer who asks why is the one building judgment instead of pattern matching. That is what you need when the pattern matcher in the room is an AI model that’s confident about everything and accountable for nothing.

Give them room to be wrong. Give them problems worth reasoning through. Give them the feedback loops to know when their judgment is off. Those are the engineers who lead teams within 18 months.

The same standards that let engineers recognize a bad AI recommendation are the ones that let them recognize a bad recommendation from a colleague, or from themselves at 11pm under pressure.

That’s on Us

If your engineers can’t defend a decision in their own words, the problem isn’t the tool they’re reaching for. You never built a culture where their judgment was trusted, tested, or developed.

That’s a leadership failure.

The fix starts with you. Not with the AI policy document. Not with the acceptable-use guidelines. With you.

With whether you ask “why” or just “when.” With whether your reviews create space for engineers to be wrong and learn, or create pressure to be right fast. With whether you’ve removed yourself as a dependency on good decisions being made, or whether your team still needs you in the room to trust itself.

A team that defers to ChatGPT over its own judgment is a team that’s been trained to defer to authority. Before the model arrived, that authority was you. I know it was me.

AI is going to keep getting better. The oracles will keep getting more confident, more accessible, more persuasive. The teams that win won’t be the ones with the best AI policies.

They’ll be the ones who built the culture where engineers can defend a decision in their own words before the oracle arrived. And the ones willing to reckon, right now, with what the oracle is exposing.

The next time an engineer says “ChatGPT recommended something else” in a review … don’t reach for the policy doc. Ask them to walk you through what they’re weighing. What are the tradeoffs? What are they watching?

That’s the conversation that builds culture. One exchange at a time, in the room where decisions actually happen.

Getting there isn’t a tooling problem. It never was.

That’s on us. All of us.

I write daily about engineering leadership at jonoherrington.com.

If I Had to Rebuild My Developer Career From Zero in 2026, I’d Do This

If I lost everything career-wise tomorrow and had to rebuild from zero, I would do it very differently than most advice on the internet suggests.

I would not start with a 9-month roadmap.
I would not buy five courses.
I would not obsess over the “perfect stack.”
I would definitely not wait until I felt ready.

I would optimize for proof.

That is the whole framework.

Not confidence.
Not credentials.
Not endless preparation.

Proof.

Step 1: Pick One Marketable Direction

Not ten.
One.

Examples:

  • frontend for product teams
  • backend for SaaS tools
  • iOS apps with SwiftUI
  • internal automation for small businesses

Most people stay stuck because they try to keep every possible path open.

That feels flexible.
It is actually paralyzing.

Specificity creates momentum.

Step 2: Build One Useful Project, Not a Portfolio Graveyard

I would build a single project with a real use case and document it properly.

Not a clone.
Not another todo app.

Something with context:

  • who it is for
  • what pain it solves
  • what tradeoffs I made
  • what I learned

One real project with clear explanation is worth more than six shallow demos.

Step 3: Learn in Public Just Enough to Be Visible

I would not try to become an influencer.

But I would publish useful artifacts:

  • short lessons
  • bug writeups
  • architecture notes
  • project updates

Because visibility matters.

Not vanity visibility.
Proof visibility.

The market needs a way to discover that you exist and that you can think.

Writing gives it that.

Step 4: Get Good at Written Communication Early

This is the unfair advantage most beginners ignore.

If you can write:

  • a sharp README
  • a clean project case study
  • a clear bug report
  • a thoughtful outreach message

you will feel more hireable faster.

Because now your skill is easier to trust.

Step 5: Target Environments Where Proof Beats Pedigree

I would not spend all my energy chasing the most competitive, prestige-heavy path first.

I would target places where visible skill matters:

  • startups
  • freelance clients
  • small product teams
  • founder-led companies
  • communities where builders get noticed

Later, if I wanted brand-name companies, I could aim there with stronger proof in hand.

Step 6: Create a Weekly Output System

Not motivation.
Output.

Every week I would aim for:

  • one build improvement
  • one public artifact
  • one outreach action

That means I am always increasing:

  • skill
  • proof
  • surface area for luck

That last one matters more than people admit.

Luck finds active people faster.

Step 7: Stop Measuring Progress by Feeling

This is where many beginners lose months.

They keep asking:

“Do I feel ready?”

Wrong metric.

I would ask:

  • what did I ship?
  • what did I publish?
  • what feedback did I get?
  • what became easier this month?

Feelings fluctuate.
Evidence is calmer.

Final Thought

If I had to rebuild from zero in 2026, I would not try to look impressive early.

I would try to become undeniable in small, concrete ways.

One project.
One clear direction.
One useful public trail.
One repeatable system.

That is enough to create momentum.

And momentum is what most developer careers are really missing in the beginning.

I write about developer careers, proof-first growth, and building enough visible leverage to stop feeling invisible.

dirham v1.3.0 — A Universal Web Component for the UAE Dirham Symbol

The UAE Dirham now has an official Unicode codepoint — U+20C3 — accepted for Unicode 18.0. But operating systems won’t ship native font support until September 2026.

dirham bridges that gap. It maps the official glyph to U+20C3 via a custom web font, so your content is semantically correct today and future-proof for when native support arrives.

What’s new in v1.3.0

The headline feature is <dirham-price> — a Web Component that formats and displays Dirham amounts in any framework, no wrappers needed.

<script type="module" src="https://cdn.jsdelivr.net/npm/dirham/dist/web-component/index.js"></script>

<dirham-price amount="1250"></dirham-price>
<dirham-price amount="5000000" notation="compact"></dirham-price>
<dirham-price amount="500" use-code></dirham-price>

It supports 8 attributes: amount, locale, decimals, notation, use-code, symbol-size, weight, and currency.

Works everywhere

Vue:

<script setup>
import "dirham/web-component";
</script>

<template>
  <dirham-price amount="1250" />
  <dirham-price amount="5000000" notation="compact" />
</template>

Angular:

import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";
import "dirham/web-component";

@Component({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `<dirham-price amount="1250"></dirham-price>`
})
export class AppComponent {}

Svelte:

<script>
  import "dirham/web-component";
</script>

<dirham-price amount="1250"></dirham-price>

React still has dedicated components with full TypeScript support:

import { DirhamPrice } from "dirham/react";

<DirhamPrice amount={1250} />
<DirhamPrice amount={750} className="text-emerald-400 text-2xl" />

Full feature set

Feature How
React SVG component <DirhamSymbol size={24} weight="bold" />
React price component <DirhamPrice amount={1250} notation="compact" />
Web Component (any framework) <dirham-price amount="1250">
CSS web font <i class="dirham-symbol"></i>
JS formatting formatDirham(1234.5) → ℃ 1,234.50
Parsing parseDirham("℃ 1,234.50") → 1234.5
Clipboard await copyDirhamSymbol()
CLI npx dirham copy
CDN jsDelivr, zero install
9 weight variants thin → black
5 font variants sans, serif, mono, arabic, default
RTL support Arabic locale with correct symbol placement

Why U+20C3?

Other approaches use Private Use Area hacks or plain text substitution. This package uses the officially assigned codepoint, which means:

  • Your content is semantically correct — search engines, screen readers, and parsers understand it
  • When Unicode 18.0 ships natively (Sep 2026), the web font gracefully becomes unnecessary — zero migration
  • The symbol behaves like $, €, and £ — it’s a real currency character

Links

npm install dirham

How to Get More GitHub Stars: The Definitive Guide (33K Stars Case Study)

How to Get More GitHub Stars: The Definitive Guide

We grew AFFiNE from 0 to 33,000 GitHub stars in 18 months. This guide covers every tactic we used — what worked, what failed, and what actually moves the needle.

Why I Wrote This

When I started marketing AFFiNE, I couldn’t find a comprehensive guide on growing GitHub stars. Most articles were surface-level fluff:

  • “Write good documentation” (okay, but then what?)
  • “Share on social media” (which platforms? how?)
  • “Build a community” (how do you start with zero users?)

This guide is different. It’s the tactical playbook I wish existed when we started.

Table of Contents

Section What You’ll Learn
Part 1 Why stars matter (and don’t matter)
Part 2 The first 100 stars (bootstrap phase)
Part 3 100 to 1,000 stars (content + community)
Part 4 1,000+ stars (scaling + virality)
Part 5 GitHub Trending strategies
Part 6 Common mistakes to avoid

Part 1: Why GitHub Stars Matter

The Real Value of Stars

Stars are credibility, not customers.

What stars actually give you:

  • ✅ Social proof when pitching investors
  • ✅ Trust signal for potential users
  • ✅ Visibility on GitHub Trending
  • ✅ Team motivation metric
  • ✅ Contributor attraction

What stars DON’T give you:

  • ❌ Guaranteed users or revenue
  • ❌ Product-market fit
  • ❌ A sustainable business

Use stars as a stepping stone, not a destination.

The Credibility Threshold

Star Count What It Signals
< 100 “New project, unknown”
100-500 “Some traction, worth trying”
500-1,000 “Legitimate project”
1,000-5,000 “Established, active community”
5,000+ “Industry-recognized”
10,000+ “Major project”

Your first goal: Cross the 1,000 star threshold as fast as possible.

Part 2: The First 100 Stars

This Phase Is “Artificial” (And That’s OK)

Your first 100 stars should come from people you know. Don’t pretend otherwise.

Why this matters:

  • New visitors check star count before engaging
  • < 100 stars = low conversion rate on everything else
  • You need this baseline before content marketing works

Tactics for 0→100

1. Personal Network Outreach

Message everyone you know in tech:

“Hey! We just open-sourced our project. Would mean a lot if you could check it out and star it if you find it interesting.”

  • Keep it personal, not mass-blast
  • Target developers who might actually use it
  • Follow up individually

2. Workspace/Conference Hustle

  • Print QR code to your repo
  • Walk around coworking spaces
  • Chat with developers at conferences
  • Ask during coffee/lunch breaks

3. Existing Communities

  • Company Slack/Discord
  • University alumni networks
  • Previous colleague groups
  • Online communities you’re already part of

More tactics: The Cold Start Problem for GitHub Projects: How to Get Your First 1,000 Stars

Part 3: 100 to 1,000 Stars

Shift to Organic Growth

Once you hit 100, your tactics should become authentic and scalable.

Content Strategy

Four types of content that work:

Type Example Purpose
Direct “Introducing [Project]” Explain what you built
Tutorial “Build X with [Project]” Show practical usage
Listicle “10 OSS tools for Y” Reach broader audience
Building in Public “How we solved X” Build community

Key principles:

  • Every post needs a clear CTA (“Star us on GitHub”)
  • Include repo link in multiple places
  • Use visuals (GIFs, screenshots)

Content deep dive: Developer Marketing Playbook: How to Reach Technical Audiences in 2026

Distribution Channels

Tier 1 (High Impact):

  • Reddit (r/programming, r/opensource, niche subreddits)
  • Hacker News (unpredictable but high ceiling)
  • Product Hunt (good for launches)

Tier 2 (Medium Impact):

  • Dev.to, Hashnode, HackerNoon
  • Twitter/X (dev community)
  • Discord/Slack communities

Tier 3 (Long-term SEO):

  • Your company blog
  • GitHub Awesome Lists
  • Documentation sites

Channel breakdown: GitHub Repo Promotion: 15 Channels That Actually Drive Stars

Awesome Lists Strategy

GitHub “Awesome” lists are curated collections (awesome-python, awesome-react, etc.).

How to get added:

  1. Find relevant awesome-* repos
  2. Read their contribution guidelines carefully
  3. Make sure your project meets their criteria
  4. Open a PR with proper formatting

Pro tips:

  • Some lists require minimum stars, tests, or docs
  • Chinese awesome lists have higher acceptance rates (75% in our experience)
  • Start with smaller, niche lists before big ones

Part 4: Scaling to 1,000+

The Compound Effect

After 1,000 stars, growth accelerates. You’ll get:

  • Organic discovery on GitHub
  • Mentions in newsletters
  • Unsolicited blog posts
  • Contributor applications

Your job shifts from “pushing” to “amplifying.”

Community Building

Create a home for your users:

  • Discord server (preferred for dev tools)
  • GitHub Discussions
  • Dedicated forum

Engage consistently:

  • Respond to issues within 24 hours
  • Thank contributors publicly
  • Share community wins

Community tactics: Developer Marketing 101: How to Grow Your Open Source Project

Combining with Product Hunt

Product Hunt can accelerate GitHub growth dramatically.

The playbook:

  1. Build PH launch → drive traffic to GitHub
  2. Spike in stars → hit GitHub Trending
  3. Trending → more organic stars
  4. Leverage momentum for press/community

PH + GitHub synergy: Product Hunt for Open Source: The Step-by-Step Playbook

Part 5: GitHub Trending

Why Trending Matters

GitHub Trending page is massive exposure:

  • Thousands of developers browse it daily
  • One day on Trending = 500-2,000 new stars
  • Creates cascading visibility

Factors That Affect Trending

Factor Impact
Star velocity High — stars per hour/day
Recent activity Medium — commits, issues, PRs
Language category Medium — less competition in niche languages
Account signals Low — but new accounts count less

Trending Tactics

  1. Coordinate your push — Launch content, notify community, post on social all in the same 24-48 hour window

  2. Time it right — Weekdays, avoid holidays, mornings PT

  3. Pick your language — “TypeScript Trending” easier than “All Languages Trending”

  4. Sustain momentum — Don’t just spike; maintain activity for multiple days

Complete breakdown: GitHub Star Growth: 7 Proven Tactics That Got Us 33k Stars

Part 6: Common Mistakes

1. Launching Too Early

Promoting with < 100 stars = low conversion on everything.

Fix: Get your first 100 from your network before any public promotion.

2. One Big Push, Then Nothing

Growth requires consistency, not single events.

Fix: Plan ongoing content/promotion, not just launch day.

3. Ignoring Issues

Nothing kills a project’s reputation faster than unresponded issues.

Fix: Respond within 24 hours, even if just to acknowledge.

4. Poor README

Your README is your landing page. First impressions matter.

README checklist:

  • [ ] Clear one-sentence description
  • [ ] Screenshot or GIF at top
  • [ ] Quick start guide (< 5 steps)
  • [ ] Feature list
  • [ ] Contributing link
  • [ ] License

5. No Clear CTA

If you don’t ask for stars, you won’t get them.

Fix: Include “⭐ Star us on GitHub” in content, docs, and social posts.

The AFFiNE Journey: Timeline

Month Stars Key Events
0 0 Launch
1 1,000 Product Hunt #1, initial PR
3 5,000 Reddit viral post
6 10,000 Consistent content strategy
12 25,000 HN front page, multiple Trending
18 33,000 Sustained organic growth

Full case study: How I Got 33K GitHub Stars: The Complete Marketing Playbook

Complete Resource Library

GitHub Growth

Product Launch

Developer Marketing

Key Takeaways

  1. First 100 stars are artificial — Get them from your network
  2. Content + Distribution = Growth — Write once, distribute everywhere
  3. Consistency beats intensity — Weekly content > one viral post
  4. GitHub Trending is the multiplier — Coordinate your efforts for spikes
  5. Stars ≠ users — But they build the credibility to get users

Free Resources

📘 Gingiris Open Source Marketing — Complete OSS marketing playbook

📗 Gingiris Launch Playbook — Product launch strategies

📙 Gingiris B2B Growth — PLG and SLG growth tactics

Got questions? Drop a comment or find me on Twitter @iris_carrot.

Build a Real-Time Social Media App with InsForge, MiniMax, and Next.js

InsForge AI Gateway

Introduction

In this tutorial, we will build a full-stack social platform where users post, like, repost, follow each other, get real-time notifications, and chat with an in-app AI assistant.

Here is what we will be building:

  • A Next.js frontend with a real-time feed, post composer, profile pages, notifications, explore, and an AI chat screen
  • InsForge as the backend platform, managing the database, auth, file storage, real-time pub/sub, and AI gateway from a single place
  • MiniMax M2.7 via GitHub Copilot as the agent that builds the entire application through InsForge Agent Skills and MCP.
  • Google Stitch for generating the design reference before the agent builds
  • Deployment triggered from inside GitHub Copilot, with no manual steps outside the editor

By the end, you will have a working social platform template you can fork and adapt to whatever you are building next.

Let’s get started.

What Is InsForge

InsForge is an open-source backend platform that bundles a Postgres database, a REST API layer via PostgREST, an AI model gateway that routes to any OpenRouter-compatible model, a real-time pub/sub system, serverless edge functions, and a CLI, all into a single deployable platform. You can self-host it with Docker or use the managed cloud. You bring the application logic. InsForge handles what’s underneath.

What We Are Using InsForge For

Three things in particular make InsForge the right fit for a project like this one.

Agent Skills: When you run insforge create, the CLI installs a .agents/ folder into your project. That folder contains the InsForge SDK documentation, API patterns, and auth setup in a format the agent can read directly. Before the agent writes a single file, it reads that folder. This is why the build prompt can stay short. The agent already knows how to talk to InsForge before you type anything.

The AI gateway: InsForge manages the AI provider keys automatically on the backend, you don’t need to put an OpenRouter key in your frontend .env file. From there, any AI call in your frontend app using the SDK hits one InsForge endpoint and passes a model string. To swap models, you simply change that string; nothing else in the codebase needs to be touched. The backend gateway securely routes the request through OpenRouter, supporting models from OpenAI, Anthropic, Google, DeepSeek, X-AI, and more.

InsForge AI Gateway

The PostgREST layer: Every table in your InsForge database is automatically a REST endpoint. The agent writes queries against the InsForge SDK. There is no data access layer to build, no custom API routes to wire up. You describe the schema, and the endpoints are there.

Setting Up the Project

Every InsForge project starts with the CLI. Install it once globally, log in, and you are set for every project you build after this.

npm install -g @insforge/cli
insforge login

That is a one-time setup. From here on, every time you want to start a new project, you create a folder and run insforge create inside it.

mkdir ripple
cd ripple
insforge create

The CLI asks you to pick a template. We picked Next.js. After that, it installs the Agent Skills, writes skills-lock.json, and asks if you want to set up deployment now. Say no for now. We will come back to that at the end.

CLI

One more thing, before you start building, install the MCP server. The quickest way is through the InsForge VS Code extension. Install it from the marketplace, and it will show you a one-click option to connect the MCP. Once done, you will see the MCP Connected indicator in the top-right corner of your InsForge dashboard, and your agent is ready to act.

InsForge Dashboard

Designing with Google Stitch

Before writing a single prompt, we used Google Stitch to design the UI for Ripple. We used this prompt to get started:

Build a social media app called Ripple. Amber gold (#F59E0B) as the primary color.
Screens: feed, composer, profile, notifications, Wave AI chat, auth screens.

Stitch exports a design.md file with the full design system, colors, typography, component structure, and screen layouts.

Google Stitch

Copy that file and save it in your project root in VS Code. When you reference it in your agent prompt, the agent has all the visual context it needs upfront, so you are not going back and forth on colors or layout later.

With the design in place, we had everything the agent needed to build the UI and wire the backend in a single pass. Time to write the prompt.

Building the App

We used GitHub Copilot as the agent, running MiniMax M2.7*,* because it handles long multi-step tasks well and stays on track across a full project build. We gave it one prompt:

Build a social media app called Ripple using InsForge as the backend platform.
Use InsForge MCP Server for all operations.

Features:
- Auth: sign up, login with name, @handle, email, password
- Feed: post (called Ripple) with text + image/video upload, like (Wave),
  repost (Spread), reply, bookmark
- Realtime feed updates
- Post composer with draft save
- Profile page with cover, avatar, bio, followers/following
- Notifications: likes, replies, follows, mentions
- Explore: trending topics, suggested users
- Wave AI: chat interface connected to InsForge AI gateway via OpenRouter
- Wave AI has collapsible right panel with chat history and bookmarks
- Deploy on InsForge

Follow the design system in design.md for colors, typography, and components.
Use InsForge for all backend. Read .agents folder for skills.

Before touching any file, the agent read .agents/skills/insforge/ to understand the InsForge SDK, then laid out the full database schema profiles, ripples, waves, spreads, follows, notifications, drafts, ai_chat_history, and more, and created a build plan for itself. Only after that did it start writing code.

Vs code IDE

The file structure was produced in one pass:

ripple/
├── src/app/
│   ├── feed/page.tsx
│   ├── profile/[handle]/page.tsx
│   ├── notifications/page.tsx
│   ├── ripple/[id]/page.tsx
│   └── wave/page.tsx
├── src/components/
│   ├── ripple/RippleCard.tsx
│   └── ripple/RippleComposer.tsx
├── src/lib/
│   ├── insforge.ts
│   └── auth-context.tsx
└── .agents/
    └── skills/insforge/

What is worth noticing here is that insforge.ts is not a custom wrapper; the agent read the skill and knew exactly how to initialize the InsForge client.

Same with auth-context.tsx: it wired sessions directly to InsForge Auth without any manual setup from us. Now, all of this came from one prompt. But what the agent actually built inside each of these files, how it handled auth sessions, how it wired realtime, how AI talks to the InsForge gateway, that is where things get interesting. So let’s see exactly what agent built inside each of those files.

What InsForge Handled, Feature by Feature

Let’s start with auth, since that is what everything else depends on.

Auth

Authentication in Ripple runs entirely through InsForge Auth: sign up, email verification, login, and session management. All the state stays in a single React Context, the agent is generated and wired up in one pass.

Auth via InsForge

Sign-up is a two-step flow. The agent calls insforge.auth.signUp(), checks if email verification is required, and stores the pending profile in localStorage until the OTP is confirmed. Once verified, it inserts the profiles record using the authenticated user ID.

const { data } = await insforge.auth.signUp({ email, password, name });
if (data?.requireEmailVerification) {
  localStorage.setItem("ripple_pending_name", name);
  return { requireEmailVerification: true };
}

// after OTP confirmed
await insforge.database.from("profiles").insert([{
  id: data.user.id, name: pendingName, handle: pendingHandle, email,
}]);

The signup page tracks a step state that switches between the form and the verify screen. Login is simpler, one call to insforge.auth.signInWithPassword() and the session is set.

Our App UI

Database

With auth out of the way, the agent moved on to the database. InsForge runs on PostgreSQL under the hood, and every table gets automatically exposed as a REST endpoint through PostgREST, which means the agent never had to write a single custom API route.

The schema the agent built covers the full surface area of the app. The core tables are profiles, ripples, ripples_media, waves (likes), spreads (reposts), follows, notifications, and ai_chat_history for the Wave AI sessions. The notifications table also has a Postgres trigger attached to it, so every insert immediately fires a real-time broadcast over the WebSocket.

InsForge DB

-- setup_trigger.sql
CREATE OR REPLACE FUNCTION notify_new_notification()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM pg_notify(
    'new_notification',
    json_build_object(
      'id', NEW.id,
      'user_id', NEW.user_id,
      'type', NEW.type,
      'actor_id', NEW.actor_id,
      'ripple_id', NEW.ripple_id
    )::text
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Because PostgREST understands foreign keys, the agent could request deeply nested relational data in a single query rather than chaining multiple fetches. Here is the feed query from page.tsx, which pulls ripples alongside their author profiles, attached media, waves, and spreads in one request:

// page.tsx — fetching the main feed
const { data, error } = await insforge.database
  .from("ripples")
  .select(`
    *,
    profiles (*),
    ripples_media (*),
    waves (*),
    spreads (*)
  `)
  .is("reply_to", null)
  .order("created_at", { ascending: false })
  .limit(50);

The profiles (*) in the select string is where PostgREST detects the foreign key between ripples.user_id and profiles.id and performs the join automatically on the backend, returning the author’s data nested inside each post object. The same pattern applies to waves and spreads, so the UI always knows the engagement state of a post without a second request.

Storage

The database takes care of structured data, but for every file, avatars, cover photos, and post media, the agent provisioned three separate InsForge Storage buckets: avatars, covers, and ripples.

Storage

InsForge Storage is S3-compatible and sits natively beside the auth and database layers, so the SDK handles uploads, hashing, and public URL generation in a single call without any custom middleware.

For profile photos, the agent used .uploadAuto(), which takes a File object and returns a public URL directly. After each upload resolves, it immediately writes that URL back to the profiles table in the database.

// profile/edit/page.tsx
if (avatar) {
  const { data, error } = await insforge.storage
    .from("avatars")
    .uploadAuto(avatar);
  if (error) throw error;
  avatarUrl = data.url;
}

if (cover) {
  const { data, error } = await insforge.storage
    .from("covers")
    .uploadAuto(cover);
  if (error) throw error;
  coverUrl = data.url;
}

await insforge.database
  .from("profiles")
  .update({ avatar_url: avatarUrl, cover_url: coverUrl })
  .eq("id", user.id);

For post media, the pattern is slightly different because a single ripple can carry up to four attached images. The agent wrote a loop that runs after the post row is created, uploads each file to the ripples bucket, and inserts a matching record into ripples_media that binds the file URL back to the post’s ID.

// RippleComposer.tsx
for (const file of media) {
  const { data: uploadData, error } = await insforge.storage
    .from("ripples")
    .uploadAuto(file);

  if (error || !uploadData) throw error;

  await insforge.database.from("ripples_media").insert([{
    ripple_id: ripple.id,
    bucket: uploadData.bucket,
    key: uploadData.key,
    url: uploadData.url,
    type: file.type.startsWith("video") ? "video" : "image",
  }]);
}

Realtime

With the database writing data correctly, the next thing the app needed was for that data to reach every connected client without a page refresh. InsForge Realtime runs on WebSockets, and the agent wired up four live channels: ripples for the global feed, ripples_media for media updates, trending_topics for live topic changes, and notifications:% for per-user alerts.

InsForge Realtime

The feed component subscribes to ripples on mount and handles two event types: INSERT for new posts and UPDATE for engagement count changes.

// page.tsx — feed subscription
const response = await insforge.realtime.subscribe("ripples");

if (response.ok) {
  insforge.realtime.on("INSERT", async (payload) => {
    const newRipple = payload.new as Ripple;
    if (!newRipple.reply_to) {
      const { data } = await insforge.database
        .from("ripples")
        .select("*, profiles (*), ripples_media (*), waves (*), spreads (*)")
        .eq("id", newRipple.id)
        .single();
      if (data) setRipples((prev) => [data as Ripple, ...prev]);
    }
  });

  insforge.realtime.on("UPDATE", (payload) => {
    const updated = payload.new as Ripple;
    setRipples((prev) =>
      prev.map((r) =>
        r.id === updated.id
          ? { ...r, wave_count: updated.wave_count, spread_count: updated.spread_count }
          : r
      )
    );
  });
}

The INSERT payload only carries the raw new row, so the agent does a quick .select() with joins before pushing it into the state, same pattern as the feed query from the Database section. The UPDATE handler just patches the counts in-place without refetching the full post.

For notifications, the Postgres trigger from setup_trigger.sql does the broadcasting on the database side. When a new row hits the notifications table, the trigger publishes directly to notifications:{user_id} over the WebSocket, and realtime-context.tsx picks it up on the frontend to increment the bell count instantly.

Realtime Architecture

AI Gateway

After real-time, the agent focused on the AI gateway. Ripple comes with an in-app AI called Wave AI. Instead of connecting directly to OpenAI or Anthropic, dealing with separate billing, and worrying about exposing keys on the frontend, it uses InsForge’s AI gateway. This gateway manages routing, authentication, and model access all in one place.

The gateway call follows the same shape as the OpenAI SDK, so it feels familiar:

const completion = await insforge.ai.chat.completions.create({
  model: "anthropic/claude-sonnet-4-5",
  messages: [
    {
      role: "system",
      content: `You are Wave AI, a helpful assistant on the Ripple social platform. You are talking to ${profile?.name || "a user"}.`,
    },
    ...pastMessages,
    { role: "user", content: userMessage.content },
  ],
});

const reply = completion.choices[0]?.message?.content;

Swapping the model is one line, change "anthropic/claude-sonnet-4-5" to "openai/gpt-4o" or any other model the gateway supports, and nothing else changes.

One thing the AI gateway doesn’t do on its own is remember past conversations. Every time you call insforge.ai.chat.completions.create, it only knows what’s in the messages array you pass. Close the tab and that’s gone.

So the agent added two database tables, ai_chat_sessions to group conversations, and ai_chat_history to store individual messages. Every time the user sends a message, it gets written to the database. Every time Wave AI replies, that gets written too. When you come back to the /ai page later, a useEffect fetches that session and loads all the messages back in. The conversation picks up exactly where it left off.

Wave AI Demo

With auth, database, storage, realtime, and Wave AI all working, the app is ready to run, and it’s time to test it locally.

Running Locally

Before deploying, run the app locally to make sure everything works end-to-end.

npm install
npm run dev

Open http://localhost:3000, sign up with a test account, go through the full flow, auth, posting a Ripple, checking the feed. If your InsForge credentials are in .env.local, everything should work on the first run.

Demo 2

Note: InsForge takes care of all the backend wiring, but the frontend is yours to shape. I made a few tweaks to the UI, adjusting the layout and refining some interactions, to make it feel more like my own, and that is the nice part: the backend is handled, so you can spend your time on the experience instead.

Deploying from GitHub Copilot

Once everything worked locally, deploying took one prompt:

Deploy to InsForge.

The agent read the project config, picked up the credentials, and called the create-deployment MCP tool, all from inside Copilot. No browser dashboard, no separate deploy config.

IDE chat

It zipped the source, uploaded it, and InsForge ran npm install and npm run build in a container with the environment variables injected. The live URL came back in the terminal.

What’s Next

At this point, you have a fully working social platform running on InsForge. Auth, a real-time feed, media uploads, notifications, and an AI assistant, all live and deployable from inside GitHub Copilot.

From here, the project is yours to extend. Swap the AI model by updating one value in the InsForge dashboard. Replace the schema entirely, and the same SDK patterns, the same Agent Skills, and the same deployment flow all carry forward to whatever you build next. You can fork the project repo and start from there.

To learn more about InsForge, check out the GitHub repo.

Product Hunt Launch Playbook: The Definitive Guide (30x #1 Winner)

Product Hunt Launch Playbook: The Definitive Guide

I’ve launched on Product Hunt 30+ times and won #1 Daily on 30 of them. This isn’t another generic guide — it’s the exact playbook we used at AFFiNE to get 33,000 GitHub stars.

What You’ll Learn

This guide consolidates everything I’ve written about Product Hunt launches into one resource:

Topic What’s Covered
Strategy Why PH matters, setting goals, timing
Preparation 6-week timeline, assets, community
Launch Day Hour-by-hour tactics
Conversion Turning traffic into users
Open Source Special tactics for OSS projects

Part 1: Strategy Foundation

Why Product Hunt Still Matters in 2026

Product Hunt isn’t a growth channel — it’s a validation and momentum accelerator.

The real value:

  • 🎯 Targeted audience: Early adopters actively seeking new tools
  • 📧 Email capture opportunity: 1,000-3,000 leads from a #1 launch
  • 🔗 Backlinks & PR: Featured in newsletters, picked up by media
  • ✅ Social proof: “#1 on Product Hunt” badge has weight

What PH is NOT:

  • ❌ A sustainable customer acquisition channel
  • ❌ A place for “finished” products (early adopters want to discover)
  • ❌ Something you can game with fake votes

Deep dive: Product Hunt Launch Strategy: From Zero to #1 Daily

Setting the Right Goals

Stop optimizing for upvotes. Upvotes are vanity metrics.

Your real KPIs:

  1. Email signups (target: 1,000+)
  2. Quality comments (engagement signals)
  3. Conversion rate (visitors → signups)
Launch Result Expected Traffic Realistic Email Capture
Top 10 2,000-3,000 200-400
Top 5 5,000-7,000 500-800
#1 Daily 10,000+ 1,000-3,000

Part 2: The 6-Week Preparation Timeline

Week 1-2: Foundation

Build your seed audience first. This is the #1 mistake founders make.

You need 400+ supporters before launch:

  • Newsletter subscribers
  • Twitter followers who engage
  • Community members you’ve helped
  • Beta users

Actions:

  • [ ] Audit your existing audience
  • [ ] Start a “launching soon” waitlist
  • [ ] Join 3-5 adjacent communities (Indie Hackers, relevant subreddits)

Week 3-4: Community Building

Product Hunt amplifies momentum. It doesn’t create it.

Spend these weeks:

  • Helping others in startup communities
  • Sharing genuine value (not promoting)
  • Building relationships with potential supporters

Checklist: Startup Launch Checklist: 47 Tasks Before, During & After Launch Day

Week 5: Asset Preparation

Your PH listing:

  • Tagline: < 60 characters, benefit-focused
  • Description: Problem → Solution → Proof
  • Images: 4-6 high-quality screenshots or GIFs
  • First comment: Your maker story (draft it now)

Your website:

  • Clear CTA above the fold
  • Email capture form ready
  • Fast loading (< 2s)
  • Mobile optimized

Week 6: Final Prep

  • [ ] Schedule launch for Tuesday-Thursday
  • [ ] Brief your supporters (but don’t ask for votes yet)
  • [ ] Test all links and forms
  • [ ] Prepare email automation for new signups
  • [ ] Write social media posts for launch day

Part 3: Launch Day Execution

Timing

Launch at 12:01 AM Pacific Time to get the full 24-hour window.

Best days: Tuesday, Wednesday, Thursday
Avoid: Monday (high competition), Friday (low traffic), Weekends

The First Hour (Critical)

  1. Post your maker comment immediately — Tell your story, not your features
  2. Notify seed audience — “We just launched, would love your feedback”
  3. Start responding to comments — Every single one

The Quality Algorithm

Product Hunt’s ranking isn’t just about vote count. It weighs:

Factor Weight What It Means
Account age High Votes from 6+ month accounts matter more
Engagement High Comments and time-on-page
Authenticity High Natural traffic patterns
Vote velocity Medium Steady growth, not spikes

What gets you penalized:

  • ❌ Mass votes from new accounts
  • ❌ Vote exchange groups
  • ❌ Asking people to “upvote” (ask for “feedback” instead)

Tactics deep dive: Product Hunt Launch: 7 Tactics That Got Us #1 (30 Times)

Hour-by-Hour Checklist

Hours 1-4 (12am-4am PT):

  • Post maker comment
  • Notify core supporters
  • Respond to early comments

Hours 5-12 (4am-12pm PT):

  • Monitor ranking
  • Continue engaging
  • Share on social (not asking for votes)
  • Brief supporters in different time zones

Hours 13-20 (12pm-8pm PT):

  • Peak traffic time
  • Maximum engagement
  • Update maker comment if needed

Hours 21-24 (8pm-12am PT):

  • Final push
  • Thank supporters
  • Plan post-launch follow-up

Part 4: Converting Traffic

Email Capture Strategy

Offer something valuable in exchange for email:

  • Free template or resource
  • Early access to new features
  • Exclusive community access
  • Launch discount

Landing page formula:

Headline: Clear benefit
Subhead: How you deliver it
Social proof: Logos, numbers, testimonials
CTA: Single, clear action (email signup)

Post-Launch Email Sequence

Set this up BEFORE launch:

Email Timing Content
1 Immediate Welcome + immediate value
2 Day 2 Product walkthrough
3 Day 4 Case study / social proof
4 Day 7 Limited offer
5 Day 10 Final CTA

Part 5: Open Source Special Tactics

If you’re launching an open source project, the game is different.

GitHub Stars as Secondary KPI

For OSS, track both:

  1. Email signups (primary)
  2. GitHub stars (secondary)

Stars provide:

  • Credibility for future fundraising
  • Community validation
  • Contributor attraction

OSS-specific guide: Product Hunt for Open Source: The Step-by-Step Playbook

Combining PH + GitHub Growth

The AFFiNE playbook:

  1. Launch on PH → Drive traffic to GitHub
  2. Hit GitHub Trending → More organic stars
  3. Leverage stars for press/community building
  4. Repeat with new features

GitHub growth deep dive: How I Got 33K GitHub Stars: The Complete Marketing Playbook

The Cold Start Problem

Getting your first 1,000 stars is the hardest part.

Phase 1 (0-100 stars): Your personal network
Phase 2 (100-1,000 stars): Content + communities
Phase 3 (1,000+ stars): Organic + viral moments

Cold start tactics: The Cold Start Problem for GitHub Projects: How to Get Your First 1,000 Stars

Part 6: After the Launch

Day 2-7: Follow Up

  • [ ] Send thank you messages to top engagers
  • [ ] Reply to any unanswered comments
  • [ ] Share launch results on social
  • [ ] Start nurturing email list

Week 2-4: Capitalize

  • [ ] Reach out to people who showed interest
  • [ ] Write a “lessons learned” post
  • [ ] Plan your next launch (yes, you can launch again)

Long Term

Product Hunt isn’t one-and-done. You can launch:

  • Major new features
  • V2 or rebrand
  • Different product angles

We launched AFFiNE multiple times over 18 months.

Complete Resource Library

I’ve written extensively about each part of this process:

Product Hunt

GitHub Stars

General Launch

Key Takeaways

  1. Prepare 6 weeks ahead — PH amplifies momentum, doesn’t create it
  2. Focus on email capture — Upvotes are vanity, emails are value
  3. Quality > Quantity — 100 engaged users beat 1,000 random votes
  4. Engage authentically — Respond to every comment
  5. Plan for multiple launches — It’s a campaign, not a one-time event

Free Resources

📘 Gingiris Launch Playbook — Full open-source guide with templates

📗 Gingiris Open Source Marketing — OSS-specific tactics

📙 Gingiris B2B Growth — PLG and SLG strategies

Questions? Drop a comment below or find me on Twitter @iris_carrot.

The Best Engineers I Know Are Not the Fastest. They’re the Clearest.

There is a type of developer everyone quietly trusts.

They are not always the flashiest person on the team.
They are not the fastest typist.
They are not the person posting screenshots of 14-hour coding sessions.

But when something matters, people want them involved.

Why?

Because they are clear.

Clear in how they think.
Clear in how they code.
Clear in how they explain tradeoffs.
Clear in how they reduce chaos around everyone else.

That is a bigger advantage than raw speed.

Speed Is Overrated Without Clarity

Fast developers can create a lot of movement.

But movement is not always progress.

I have seen extremely fast developers:

  • ship unreadable code
  • make unclear decisions
  • leave weak documentation
  • create fixes nobody understands later

For a while, they look impressive.

Then the maintenance bill arrives.

That is when clarity starts to matter more than velocity.

What Clear Engineers Actually Do

They tend to do a few things consistently:

1. They name things well

Variables. functions. modules. tickets. decisions.

They reduce ambiguity instead of spreading it.

2. They separate signal from noise

They can look at a messy problem and say:

“This is the real issue. The rest is downstream.”

That is an elite skill.

3. They explain tradeoffs honestly

Not:

“This is the best solution.”

But:

“This is the simplest solution under current constraints. We can revisit if scale changes.”

That makes teams trust them.

4. They leave clean traces

Good PR descriptions.
Useful comments.
Readable commits.
Thoughtful postmortems.

They do not just solve problems.
They make future work easier.

Why Teams Reward This So Much

Because unclear engineers are expensive.

Even if they are smart.

Unclear work creates:

  • slower reviews
  • weaker onboarding
  • harder debugging
  • duplicated effort
  • fragile systems

Clear work does the opposite.

It lowers the cognitive cost of collaboration.

And in real teams, that is worth a lot.

The Mistake Many Juniors Make

They assume seniority looks like knowing more.

Sometimes it does.

But what often looks senior in practice is this:

  • asking sharper questions
  • making simpler decisions
  • reducing complexity
  • communicating intent clearly

That is why some people feel senior in a room long before they have the title.

They create clarity under pressure.

How to Build More Clarity

You do not need a personality transplant.

Start with small habits:

  • write the problem before you solve it
  • make PRs smaller
  • explain why, not just what
  • rename things until they feel obvious
  • choose simple solutions more often

Clarity is rarely a talent.
It is usually a discipline.

Final Thought

The best engineers I know make hard things feel understandable.

That is their magic.

Not speed.
Not complexity.
Not brilliance that nobody else can follow.

Clarity.

And clarity scales better than hype ever will.

I write about engineering judgment, readable systems, and the quiet habits that make developers easier to trust and harder to ignore.

Unlocking the Digital Revolution in Sports Card Trading

In recent years, sports card trading has experienced an impressive resurgence. Once a hobby limited to physical trade shows and online marketplaces, the sports card market has rapidly evolved into a dynamic, investment-driven ecosystem. With millions of collectors, hobbyists, and investors participating, the industry has embraced technology to provide more transparency, track trends, and create opportunities. But how exactly does sports card trading work in this new, digitally connected world, and what makes it an ideal area for tech-savvy developers to dive into?

What Are Sports Cards?

Sports cards are collectible items featuring athletes, typically from various sports like baseball, basketball, football, and more. They often contain important player details, stats, and sometimes, rare features like autographs or memorabilia. Some cards have immense value, especially when the player on the card achieves great things in their career.

Why Sports Cards Are a Big Deal in 2023

The resurgence of sports cards can largely be attributed to their transformation into a new type of asset for investors. It’s no longer just about trading cards for fun—it’s a thriving secondary market, with cards being traded for hundreds of thousands, if not millions, of dollars. But why are they gaining so much attention?

Rarity and Limited Editions: Certain cards are rare, with only a small number in circulation. As players like LeBron James or Tom Brady perform well, their cards become even more valuable.
Investment Potential: High-quality cards from prominent athletes have become collectible investments, with their values skyrocketing as the sports market continues to grow.
Grading Services: Companies like PSA (Professional Sports Authenticator) and Beckett Grading Services provide an official rating for cards, influencing their value based on quality, age, and condition.
Digitalization: The rise of online marketplaces, tracking platforms, and digital collectibles has made trading sports cards more accessible to a global audience.
The Digital Revolution: Why Tech and Data Matter in Sports Card Trading

In the past, collectors had to rely on paper guides or personal knowledge to assess card values. But with the advent of technology, we now have access to real-time price trends, comparative analysis, and predictive analytics. This transformation is similar to the broader digitalization of traditional markets like stocks or real estate.

_
 _

Real-Time Price Tracking: Platforms like eBay, StockX, and other card marketplaces provide live tracking of card prices. But one issue is that these marketplaces often operate independently. As a collector or investor, you may find yourself jumping between multiple sites to gather information.
Cross-Platform Comparison: Cards from the same players can vary significantly in price across different platforms. Having the ability to compare prices directly in one place helps users avoid overpaying for cards and track the best buying opportunities.
Predictive Analytics: By leveraging historical data, machine learning models can predict the future value of sports cards. This allows investors to make better decisions, optimizing their purchases and trades.
Automated Alerts: Having real-time alerts that notify users of price changes, rare card drops, or auctions ending soon is crucial. It empowers users to act quickly in a fast-paced market.
Grading and Condition Impact: Card grades have a direct effect on price. Digital platforms that track and predict card grades allow investors to know how much a high-grade card may appreciate in the future.
Tech-Driven Platforms for Sports Card Trading

As the demand for sports card trading grows, several platforms have started to integrate technology into the market.

For example, creating a sports card analytics platform would provide a comprehensive tool for collectors and investors. By aggregating data from multiple sources—marketplaces, grading services, and social media sentiment—users would be able to:

Compare card prices across different platforms
Access a centralized space for price trends and historical data
Use predictive models to forecast the future value of cards
Get alerted when a card is at its optimal buying/selling price
Manage their own portfolios of sports cards, tracking investments over time
The Developer’s Role: Opportunities in the Sports Card Market

As developers, there are countless opportunities to innovate and build tech solutions within the sports card industry. Whether it’s designing an analytics platform, creating a marketplace, or integrating blockchain for authenticity verification, the tech landscape in sports cards is ripe for innovation.

Here are a few ideas:

Sports Card Data Aggregators: Build platforms that gather real-time price data from various sources (e.g., eBay, PWCC) and present it in one easy-to-use interface.
Machine Learning Models for Price Prediction: Use historical data and player performance to predict which cards are likely to appreciate in value.
Mobile Apps for Instant Alerts: Create a mobile app where users can track their cards and receive instant price updates or alerts for rare finds.
Blockchain for Card Authentication: Develop a system that uses blockchain to authenticate and verify sports cards, ensuring their legitimacy and provenance.
Community-driven Platforms: Integrate social features where users can share insights, review cards, and collaborate with others on investments.
Why You Should Get Involved in the Sports Card Market

Whether you’re a hobbyist, a developer, or an investor, there are plenty of reasons to be involved in the sports card market. The blend of sports, data, and technology offers a rich and engaging environment for building new solutions.

By harnessing data analytics, AI, and blockchain, you can help shape the future of sports card trading and create more opportunities for fans and investors alike.

So, whether you’re working on a trading algorithm, building a price comparison tool, or thinking about creating a complete platform to monitor and analyze the value of cards, the possibilities are endless. It’s an exciting time to dive into the world of digital sports card trading, and developers have the unique opportunity to drive innovation in this growing space.

I Reviewed 50 Junior Developer Portfolios. The Same 3 Problems Kept Showing Up.

I reviewed a pile of junior developer portfolios recently, and the result was both predictable and depressing.

Most of them were not bad because the developers were untalented.

They were bad because they felt empty.

That is the portfolio problem nobody talks about.

A portfolio can look polished and still communicate almost nothing.

You open the site and see:

  • a nice hero section
  • a headshot
  • some tech stack badges
  • 3 projects
  • a contact button

Looks professional.
Still forgettable.

After going through 50 of them, I noticed the same three problems again and again.

Problem 1: The Projects Had No Stakes

Most portfolio projects describe features, not value.

Example:

“Task management app built with React, Node.js, and MongoDB.”

Okay.
Why should I care?

Who was it for?
What problem did it solve?
What was difficult about it?
What tradeoff did you make?
What did you learn?

Without stakes, a project feels like an assignment.

A better project description sounds like this:

“Built a task app for a student who kept missing deadlines. Added recurring tasks, priority sorting, and weekly review flow. Reduced the time needed to plan the week from 30 minutes to under 10.”

Now I understand there was a real problem.
Now the project has weight.

Problem 2: There Was No Proof of Thinking

This is the biggest one.

Most portfolios show output.
Very few show decision-making.

I want to know:

  • Why did you build it this way?
  • What went wrong?
  • What would you change now?
  • What constraint shaped the solution?

Even one short section called “What I learned” makes a project feel more senior.

It tells me you are not just assembling tutorials. You are reflecting on tradeoffs.

And that matters more than another screenshot carousel.

Problem 3: Everything Looked Like a Demo, Not a Person

This one is subtle.

Many junior portfolios feel like they were generated from the same template:

  • generic headline
  • generic bio
  • generic projects
  • generic stack list

Nothing feels specific.

The result is not “professional.”
It is anonymous.

A strong portfolio leaves traces of an actual person:

  • the niche you care about
  • the problems you keep solving
  • your writing style
  • your point of view
  • the kind of work you want more of

Specific beats polished.

Every time.

What Makes a Portfolio Memorable Instead

If I had to simplify it, a strong junior portfolio needs four things:

1. One clear identity

Not “full-stack developer passionate about technology.”

Try something concrete:

  • “I build fast internal tools for small teams.”
  • “I like turning messy workflows into simple web apps.”
  • “Frontend developer focused on readable product interfaces.”

This gives your portfolio a spine.

2. Two or three projects with real context

Fewer projects.
More depth.

For each project, show:

  • the problem
  • your role
  • the constraint
  • the decision
  • the result

That is far more convincing than listing seven mini-clones.

3. Writing

Yes, writing.

A paragraph that explains your thinking is a career advantage.

Most juniors avoid writing because they think code should speak for itself.
That is a mistake.

Clear writing makes your code feel more trustworthy before anyone even reads it.

4. One proof point beyond the site itself

Could be:

  • a GitHub repo with a good README
  • a short technical post
  • a case study
  • a build log
  • a before/after breakdown

That extra layer makes you feel real.

Final Thought

The best junior portfolios do not try to look like senior portfolios.

They try to make one thing obvious:

“This person can think, build, and communicate.”

That is enough.

You do not need a personal brand empire.
You need proof that your work is connected to reality.

That is what most portfolios are missing.

And that is why so many of them blend together.

I write about portfolios, developer careers, and how to turn useful work into visible proof.

CVE-2026-33650: CVE-2026-33650: Privilege Escalation via Incorrect Authorization in WWBN AVideo

CVE-2026-33650: Privilege Escalation via Incorrect Authorization in WWBN AVideo

Vulnerability ID: CVE-2026-33650
CVSS Score: 7.6
Published: 2026-03-25

WWBN AVideo versions up to and including 26.0 contain an incorrect authorization vulnerability (CWE-863). Users with the ‘Videos Moderator’ permission can exploit inconsistent authorization boundaries to transfer video ownership and delete arbitrary videos, resulting in privilege escalation.

TL;DR

A privilege escalation flaw in WWBN AVideo <= 26.0 allows ‘Videos Moderator’ users to bypass authorization checks, transfer arbitrary video ownership to themselves, and subsequently delete videos they do not own.

⚠️ Exploit Status: POC

Technical Details

  • CWE ID: CWE-863
  • Attack Vector: Network
  • CVSS Score: 7.6
  • EPSS Score: 0.00028
  • Impact: High Integrity, Low Availability
  • Exploit Status: Proof of Concept
  • KEV Status: Not Listed

Affected Systems

  • WWBN AVideo <= 26.0
  • AVideo: <= 26.0 (Fixed in: Commit 838e16818c793779406ecbf34ebaeba9830e33f8)

Code Analysis

Commit: 838e168

Fix incorrect authorization bounds in videoAddNew.json.php

- if (!Video::canEdit($_POST['id']) && !Permissions::canModerateVideos()) {
+ if (!Video::canEdit($_POST['id'])) {

Exploit Details

Mitigation Strategies

  • Upgrade WWBN AVideo to the latest patched version.
  • Audit active user roles and remove the ‘Videos Moderator’ permission from non-essential accounts.
  • Monitor access logs for suspicious sequential requests to videoAddNew.json.php and videoDelete.json.php.

Remediation Steps:

  1. 1. Backup the AVideo database and web directory.
  2. 2. Apply commit 838e16818c793779406ecbf34ebaeba9830e33f8 to the application codebase or upgrade to a release > 26.0.
  3. 3. Review the ‘users_id’ field in the video metadata database table for unauthorized ownership transfers.
  4. 4. Restart the web server application to clear any cached PHP processes.

References

Read the full report for CVE-2026-33650 on our website for more details including interactive diagrams and full exploit analysis.