DEV Community

Cover image for Building a Profitable SaaS in 7 Days: How I made $1,680.37💵
Luna Rojas
Luna Rojas

Posted on • Originally published at Medium

Building a Profitable SaaS in 7 Days: How I made $1,680.37💵

I still remember staring at my computer screen late one night, sketching out ideas for a SEO platform. Like many developers, I had a growing list of “someday” projects that never seemed to materialize.

But this time was different. Armed with Wasp Framework and a clear vision for whitehatseotactics.com, I decided to challenge myself:

“Could I build and launch a complete SaaS in just 7 days?”

⚠ Spoiler alert: Not only did I succeed, but within weeks of launch, the platform had generated $1,680.37 in revenue. This isn’t one of those “too good to be true” stories — it’s about how modern development has changed what’s possible for indie developers.

a

You see, I’ve built my fair share of SaaS applications before, and the pattern was always the same: weeks spent setting up authentication, wrestling with payment integrations, and building basic features that every SaaS needs. It was like reinventing the wheel every single time.

a

But this project was different, and I want to share exactly how.

The secret? A powerful combination of Wasp and OpenSaaS that handled all the boilerplate and infrastructure, letting me focus entirely on what made my SaaS unique. No more endless configuration files, no more authentication headaches, and definitely no more weeks spent on basic setup!

In this article, I’ll take you through my entire journey — from the initial setup to launching a profitable SaaS in just 7 days. I’ll show you how Wasp’s elegant architecture with its main.wasp file became my single source of truth, how Prisma’s schema made database management a breeze, and how features like built-in authentication and Stripe integration saved me days of development time.

a

Check out: https://whitehatseotactics.com/

But this isn’t just about the technical stack. It’s about rethinking how we approach SaaS development in 2025. Whether you’re a seasoned developer or just starting your first serious project, I believe this approach could change your development workflow too.

Let’s dive into how modern tools like Wasp Framework are making it possible to go from idea to profitable SaaS faster than ever before.


Why Wasp Framework Was My Game-Changer

As a full-stack developer, finding the right framework that balances productivity, type safety, and maintainability is crucial.

a

Source: https://wasp.sh/

After exploring various options, Wasp Framework emerged as a game-changing solution for my development workflow. Here’s why:

The Appeal of Full-Stack TypeScript

One of the most compelling features of Wasp is its first-class support for TypeScript across the entire stack. Wasp automatically generates types based on your schema and operations, providing true full-stack type safety:

// Server-side query with full type inference
import type { GetTasks } from 'wasp/server/operations'

export const getTasks: GetTasks = async (args, context) => {
  // Types for args and context are automatically inferred
  const tasks = await context.entities.Task.findMany()
  return tasks // Return type is also checked
}
Enter fullscreen mode Exit fullscreen mode
// Client-side with type-safe queries
import { useQuery } from 'wasp/client/operations'

export function TaskList() {
  // Full type safety for query data and error handling
  const { data: tasks, isLoading, error } = useQuery(getTasks)
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Single Source of Truth with main.wasp

The main.wasp file serves as a centralized configuration that ties everything together. This declarative approach eliminates the need for complex boilerplate while maintaining clarity:

app todoApp {
  wasp: {
    version: "^0.15.0"
  },
  title: "Todo App"
}

route TaskRoute { path: "/tasks", to: TaskPage }
page TaskPage {
  component: import { TaskPage } from "@src/pages/TaskPage.tsx"
}

query getTasks {
  fn: import { getTasks } from "@src/server/queries.ts",
  entities: [Task]

Enter fullscreen mode Exit fullscreen mode

The Power of Prisma Schema

Wasp leverages Prisma for database operations, providing a clean and type-safe way to define your data model:

model Task {
  id          Int      @id @default(autoincrement())
  description String
  isDone      Boolean  @default(false)
  user        User     @relation(fields: [userId], references: [id])
  userId      Int
}

model User {
  id    Int     @id @default(autoincrement())
  tasks Task[]
}
Enter fullscreen mode Exit fullscreen mode

This schema automatically generates:

  • Type-safe database queries
  • Migration scripts
  • TypeScript types for your entities
  • Full-stack type safety when used with queries and actions

How Cursor IDE Accelerated Development

While Wasp Framework provided the foundation, my development speed got an extra boost from Cursor IDE. As I built whitehatseotactics.com, I discovered that Cursor’s AI-powered features perfectly complemented Wasp’s development workflow.

a

https://www.cursor.com/

The real game-changer was Cursor’s ability to understand Wasp’s specific patterns and conventions. For example, when working with the main.wasp file, Cursor would intelligently suggest completions for routes, queries, and actions:

route DashboardRoute { 
  path: "/dashboard", 
  to: DashboardPage,
  authRequired: true
}

query getSEOMetrics {
  fn: import { getSEOMetrics } from "@src/server/queries.ts",
  entities: [Website, SEOMetrics]
}
Enter fullscreen mode Exit fullscreen mode

But where Cursor really shined was in helping me maintain consistency across my full-stack TypeScript code. When implementing new features, Cursor would suggest proper type definitions and help me maintain the connection between my server operations and client components:

// Cursor would help maintain consistency between
// server operations and client components
import { useQuery } from 'wasp/client/operations'
import type { GetSEOMetrics } from 'wasp/server/operations'

export const getSEOMetrics: GetSEOMetrics = async (args, context) => {
  const { websiteId } = args
  return context.entities.SEOMetrics.findMany({
    where: { websiteId }
  })
}
Enter fullscreen mode Exit fullscreen mode

Cursor understood Wasp’s patterns and could help generate boilerplate code for new features, saving me hours of typing.


Building the Core Features at Lightning Speed

When building whitehatseotactics.com, the speed at which I could implement core features was remarkable. Let me walk you through how Wasp’s architecture made this possible.

Authentication System Implementation

One of the most time-consuming parts of building a SaaS is usually the authentication system. With Wasp, it was surprisingly straightforward. The framework provides a built-in auth system that took minutes to set up:

app whitehatseotactics {
  wasp: {
    version: "^0.15.0"
  },
  title: "White Hat SEO Tactics",
  auth: {
    userEntity: User,
    methods: {
      usernameAndPassword: {}
    },
    onAuthFailedRedirectTo: "/login"
  }
}
Enter fullscreen mode Exit fullscreen mode

On the client side, Wasp provides ready-to-use components that I could easily customize with Tailwind:

import { LoginForm } from 'wasp/client/auth'

export function LoginPage() {
  return (
    <div className='min-h-screen flex items-center justify-center bg-gray-50'>
      <div className='max-w-md w-full space-y-8'>
        <LoginForm 
          className='mt-8 space-y-6'
          appearance={{
            submitButton: 'w-full py-2 px-4 bg-indigo-600 hover:bg-indigo-700 rounded-md'
          }}
        />
      </div>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Database Setup and Management

Setting up the database schema was incredibly efficient with Prisma. I defined my core models in schema.prisma:

model User {
  id        Int       @id @default(autoincrement())
  projects  Project[]
  websites  Website[]
  createdAt DateTime  @default(now())
}

model Website {
  id          Int      @id @default(autoincrement())
  url         String
  user        User     @relation(fields: [userId], references: [id])
  userId      Int
  seoMetrics  SEOMetrics[]
  lastScanned DateTime?
}

model SEOMetrics {
  id        Int      @id @default(autoincrement())
  website   Website  @relation(fields: [websiteId], references: [id])
  websiteId Int
  score     Int
  findings  Json
  createdAt DateTime @default(now())
}
Enter fullscreen mode Exit fullscreen mode

React TSX Components Structure

I organized my components following a feature-based structure, which Wasp made easy to maintain:

// src/features/seo-analysis/components/MetricsDisplay.tsx
import { useQuery } from 'wasp/client/operations'

export function MetricsDisplay({ websiteId }: { websiteId: number }) {
  const { data: metrics, isLoading } = useQuery(getSEOMetrics, { websiteId })

  if (isLoading) {
    return <div className='animate-pulse'>Loading metrics...</div>
  }

  return (
    <div className='grid grid-cols-3 gap-4'>
      {metrics.map(metric => (
        <MetricCard 
          key={metric.id}
          score={metric.score}
          findings={metric.findings}
        />
      ))}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

I kept my components focused and reusable, leveraging Wasp’s built-in hooks for data fetching:

// src/features/shared/components/DashboardLayout.tsx
import { useAuth } from 'wasp/client/auth'
import { Outlet } from 'react-router-dom'

export function DashboardLayout() {
  const { user } = useAuth()

  return (
    <div className='min-h-screen bg-gray-100'>
      <Sidebar user={user} />
      <main className='ml-64 p-8'>
        <Outlet />
      </main>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

TailwindCSS Integration Benefits

Wasp’s seamless integration with Tailwind CSS was a massive productivity boost. I could style components rapidly without context switching:

  1. Rapid Prototyping: Tailwind’s utility classes allowed me to build UI components quickly.
  2. Responsive Design: Building a mobile-friendly interface was straightforward:

The combination of Wasp’s structured approach to full-stack development and these modern tools allowed me to build complex features in hours rather than days. The built-in authentication, type-safe database operations, and seamless UI development created a development experience that was both enjoyable and incredibly productive.


Seamless Third-Party Integrations

One of the most impressive aspects of Wasp was how smoothly it handled third-party integrations. Here’s how I integrated essential services with the OpenSaaS Template without the usual integration headaches.

a

https://opensaas.sh/

Using this template you won’t need to do all of the following but look how easy it is!

Stripe Payment Processing

Setting up Stripe for my SaaS pricing tiers was straightforward. First, I defined the payment logic in my operations file:

// src/server/payments/operations.ts
import type { CreateSubscription } from 'wasp/server/operations'
import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)

export const createSubscription: CreateSubscription = async (args, context) => {
  if (!context.user) throw new Error('Not authorized')

  const { priceId } = args

  const session = await stripe.checkout.sessions.create({
    customer_email: context.user.email,
    line_items: [{
      price: priceId,
      quantity: 1
    }],
    mode: 'subscription',
    success_url: `${process.env.WASP_WEB_CLIENT_URL}/dashboard?success=true`,
    cancel_url: `${process.env.WASP_WEB_CLIENT_URL}/pricing`
  })

  return { sessionId: session.id }
}
Enter fullscreen mode Exit fullscreen mode

Then, I declared it in main.wasp:

action createSubscription {
  fn: import { createSubscription } from "@src/server/payments/operations.js",
  entities: [User, Subscription]
}
Enter fullscreen mode Exit fullscreen mode

And implemented the client-side component:

// src/features/billing/components/PricingCard.tsx
import { useAction } from 'wasp/client/operations'
import { loadStripe } from '@stripe/stripe-js'

export function PricingCard({ price, features }: PricingProps) {
  const createSubscriptionFn = useAction(createSubscription)
  const stripePromise = loadStripe(process.env.STRIPE_PUBLIC_KEY!)

  const handleSubscribe = async () => {
    const { sessionId } = await createSubscriptionFn({ priceId: price.id })
    const stripe = await stripePromise
    await stripe?.redirectToCheckout({ sessionId })
  }

  return (
    <div className='rounded-lg border p-6 bg-white shadow-sm'>
      <button
        onClick={handleSubscribe}
        className='w-full bg-indigo-600 text-white py-2 rounded-md'
      >
        Subscribe
      </button>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

OpenAI API Implementation

Integrating OpenAI for SEO content analysis was equally smooth:

// src/server/ai/operations.ts
import type { AnalyzeContent } from 'wasp/server/operations'
import { OpenAI } from 'openai'

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

export const analyzeContent: AnalyzeContent = async (args, context) => {
  if (!context.user) throw new Error('Not authorized')

  const { content } = args

  const completion = await openai.chat.completions.create({
    messages: [{
      role: 'system',
      content: 'You are an SEO expert analyzing content.'
    }, {
      role: 'user',
      content: `Analyze this content: ${content}`
    }],
    model: 'gpt-4'
  })

  return {
    analysis: completion.choices[0].message.content,
    score: calculateSEOScore(completion)
  }
}
Enter fullscreen mode Exit fullscreen mode

a

AWS S3 File Handling

For file uploads and storage, I integrated AWS S3:

// src/server/storage/operations.ts
import type { UploadFile } from 'wasp/server/operations'
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'

const s3Client = new S3Client({
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!
  }
})

export const uploadFile: UploadFile = async (args, context) => {
  if (!context.user) throw new Error('Not authorized')

  const { file, fileName } = args

  await s3Client.send(new PutObjectCommand({
    Bucket: process.env.AWS_BUCKET_NAME,
    Key: `users/${context.user.id}/${fileName}`,
    Body: file,
    ContentType: file.type
  }))

  return {
    url: `https://${process.env.AWS_BUCKET_NAME}.s3.amazonaws.com/users/${context.user.id}/${fileName}`
  }
}
Enter fullscreen mode Exit fullscreen mode

a

Auth System Setup

Wasp’s built-in auth system was a massive time-saver.

a

I just needed to configure it in main.wasp and create the login pages:

app whitehatseotactics {
  auth: {
    userEntity: User,
    methods: {
      usernameAndPassword: {
        allowUnverifiedLogin: false,
        onAuthFailedRedirectTo: "/login"
      },
      google: {
        configFn: import { googleAuthConfig } from "@src/server/auth/config.js"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The auth UI components were ready to use with my styling:

// src/features/auth/pages/LoginPage.tsx
import { LoginForm } from 'wasp/client/auth'

export function LoginPage() {
  return (
    <div className='min-h-screen flex items-center justify-center bg-gray-50'>
      <div className='max-w-md w-full space-y-8'>
        <LoginForm 
          appearance={{
            submitButton: 'w-full py-2 px-4 rounded-md bg-indigo-600 hover:bg-indigo-700',
            socialButton: 'w-full py-2 px-4 rounded-md border hover:bg-gray-50'
          }}
          logo={<img src='/logo.png' alt='Logo' className='h-12 w-auto' />}
        />
      </div>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

The real power came from how these integrations worked together. For example, when a user subscribes through Stripe, their auth session is automatically updated with their subscription status, and they can immediately start uploading files to S3 and using the OpenAI-powered features.

This integrated approach meant I could focus on building features rather than wrestling with authentication states, API keys, or service connections. Wasp handled all the complex integration patterns, allowing me to build a fully-featured SaaS in just 7 days.


The Technical Stack Deep Dive

Let me walk you through the technical decisions that made White Hat SEO Tactics both maintainable and scalable. The beauty of Wasp is how it brings together modern tools in a cohesive way.

Frontend Architecture Decisions

I structured my frontend using a feature-first architecture, which kept the codebase organized as features grew:

src/
  features/
    seo-analysis/
      components/
        AnalysisDashboard.tsx
        MetricsChart.tsx
      operations.ts
      types.ts
    website-management/
      components/
        WebsiteList.tsx
        AddWebsiteModal.tsx
      operations.ts
    shared/
      components/
        Layout.tsx
        Navbar.tsx
      hooks/
        useDebounce.ts
Enter fullscreen mode Exit fullscreen mode

For state management, I leveraged Wasp’s built-in query caching and real-time updates:

// src/features/seo-analysis/components/AnalysisDashboard.tsx
import { useQuery } from 'wasp/client/operations'

export function AnalysisDashboard() {
  const { data: websites, isLoading } = useQuery(getWebsites)
  const { data: metrics } = useQuery(getSEOMetrics, {
    // Automatic cache invalidation when websites change
    dependencies: [websites]
  })

  return (
    <div className='space-y-6'>
      <MetricsOverview data={metrics} />
      <WebsiteList 
        websites={websites}
        isLoading={isLoading}
      />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Backend Structure with Node.js

Wasp’s backend architecture made it easy to organize business logic and maintain clean separation of concerns:

// src/server/core/validation.ts
export const validateWebsite = async (url: string) => {
  // Shared validation logic
}

// src/server/websites/operations.ts
import type { CreateWebsite } from 'wasp/server/operations'
import { validateWebsite } from '../core/validation'

export const createWebsite: CreateWebsite = async (args, context) => {
  if (!context.user) throw new Error('Not authorized')

  await validateWebsite(args.url)

  return context.entities.Website.create({
    data: {
      url: args.url,
      userId: context.user.id,
      settings: args.settings
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

Query and Action Patterns

Wasp’s operation system provides a clean pattern for all data operations. Here’s how I structured my queries and actions:

// main.wasp
query getWebsiteMetrics {
  fn: import { getWebsiteMetrics } from "@src/server/metrics/operations.js",
  entities: [Website, SEOMetrics]
}

action updateWebsiteSettings {
  fn: import { updateWebsiteSettings } from "@src/server/websites/operations.js",
  entities: [Website]
}
Enter fullscreen mode Exit fullscreen mode

Implementation with type safety:

// src/server/metrics/operations.ts
import type { GetWebsiteMetrics } from 'wasp/server/operations'

export const getWebsiteMetrics: GetWebsiteMetrics = async ({ websiteId }, context) => {
  if (!context.user) throw new Error('Not authorized')

  return context.entities.SEOMetrics.findMany({
    where: { 
      websiteId,
      website: { userId: context.user.id }
    },
    include: {
      website: true
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

Client-side usage becomes straightforward:

// src/features/metrics/components/MetricsView.tsx
import { useQuery, useAction } from 'wasp/client/operations'

export function MetricsView({ websiteId }: { websiteId: number }) {
  const { data: metrics } = useQuery(getWebsiteMetrics, { websiteId })
  const updateSettingsFn = useAction(updateWebsiteSettings)

  const handleSettingsUpdate = async (settings: WebsiteSettings) => {
    await updateSettingsFn({
      websiteId,
      settings
    })
  }

  return (
    // Component implementation
  )
}
Enter fullscreen mode Exit fullscreen mode

Database Design Choices

I used Prisma’s schema to define clear relationships and constraints:

model User {
  id        Int       @id @default(autoincrement())
  websites  Website[]
  plan      Plan      @default(FREE)
  createdAt DateTime  @default(now())
}

model Website {
  id          Int         @id @default(autoincrement())
  url         String      @unique
  user        User        @relation(fields: [userId], references: [id])
  userId      Int
  metrics     SEOMetrics[]
  settings    Json?
  lastScanned DateTime?
}

model SEOMetrics {
  id        Int      @id @default(autoincrement())
  website   Website  @relation(fields: [websiteId], references: [id])
  websiteId Int
  score     Int
  findings  Json
  createdAt DateTime @default(now())

  @@index([websiteId, createdAt])
}

enum Plan {
  FREE
  PRO
  ENTERPRISE
  ENTERPRISE<br>}</span>
Enter fullscreen mode Exit fullscreen mode

Key database design decisions included:

1. Using JSON fields for flexible storage of settings and findings

2. Creating appropriate indexes for common queries

3. Implementing soft deletes for important data

4. Using enums for fixed value sets like subscription plans

This technical foundation allowed me to:

  • Scale efficiently as user base grew
  • Maintain type safety across the stack
  • Add features quickly without breaking existing functionality
  • Keep the codebase organized and maintainable

The combination of Wasp’s structured approach with these architectural decisions meant I could move fast without sacrificing code quality or scalability.


From Development to Deployment

After building the core features of whitehatseotactics.com, I focused on a strategic launch that would maximize early adoption and revenue. Here’s how I approached each phase:

Launch Strategy

I followed a three-phase launch approach:

1. Soft Launch (Days 1–2)

  • Released with basic pricing tiers

2. Marketing Push (Days 3–5)

  • Posted on Product Hunt
  • Shared on Twitter/X
  • Engaged with SEO communities
  • Started content marketing with blog posts

3. Full Launch (Days 6–7)

  • Enabled all payment tiers
  • Started running targeted ads

And take profit 💵.

Early User Feedback

The feedback loop was crucial for quick improvements:

  • Feedback Collection
  • Monitored user behavior through analytics
  • Quick Iterations
  • Fixed reported bugs within hours
  • Improved UX based on session recordings
  • Updated pricing based on user suggestions

Revenue Generation Approach

My revenue strategy focused on providing immediate value:

  1. Pricing Structure
  • Free tier: 3 basic SEO tactics
  • Pro tier ($27): 25 advanced tactics
  • Lifetime deal ($49): All 100+ tactics

2. Revenue Streams

  • Direct sales through tiered pricing
  • Upsells for additional features
  • Affiliate commissions
  • Custom enterprise solutions

3. Key Results

  • First sale within 24 hours of launch
  • Reached $1,680.37 in revenue
  • 42% conversion rate from free to paid

The rapid deployment was possible thanks to Wasp’s built-in features and seamless integration with services like Stripe. The auth system implementation made user management straightforward.


Key Takeaways

Looking back at building whitehatseotactics.com, I’ve gathered valuable insights about rapid SaaS development with Wasp Framework. Here’s what I learned and where I’m headed next.

What Worked Exceptionally Well

  1. Wasp Framework’s Core Features
  • Auth system implementation saved 2–3 days of development time
  • Prisma schema made database changes painless
  • TypeScript integration caught errors early
  • Built-in deployment pipeline simplified launch

2. Development Workflow

// Example of Wasp's elegant operation definitions
query getSEOMetrics {
  fn: import { getSEOMetrics } from "@src/server/metrics/operations.js",
  entities: [Website, SEOMetrics]
}

action updateMetrics {
  fn: import { updateMetrics } from "@src/server/metrics/operations.js",
  entities: [Website, SEOMetrics]
}
Enter fullscreen mode Exit fullscreen mode

3. Tech Stack Choices

  • TailwindCSS for rapid UI development
  • React + TypeScript for robust frontend
  • Prisma for type-safe database operations
  • Stripe for seamless payments

The experience of building whitehatseotactics.com with Wasp has proven that rapid SaaS development doesn’t mean sacrificing quality or scalability. The framework’s robust features and elegant architecture have provided a solid foundation for future growth.

Moving forward, the focus will be on scaling the infrastructure, expanding features, and growing the user base while maintaining the agility that made the initial development so successful.

Top comments (19)

Collapse
 
bbkr profile image
Paweł bbkr Pabian

Beware!

FOMO popup with "3 lifetime spots left" and popups that people with generated names are just buying them out shows it all.

This may be a scam and article from fresh account was generated only to drive traffic to this product.

Collapse
 
heyitslunarojas profile image
Luna Rojas

Yes, and Wasp Framework is also created by me and contains a malware.

Collapse
 
bbkr profile image
Paweł bbkr Pabian

OMG! Priya R. just bought it again! What an awesome product!

Sorry, but who are you trying to fool? Your site is lying to user from pixel 0,0 - fake product availability is classified as "False use of limited offers" by EU law: europa.eu/youreurope/citizens/cons....

So we have:

  • account that only did one post
  • financial claims in the title
  • false offers on site

One red flag after another...

Collapse
 
cgagnonqc profile image
Cedric

Thank you a lot for sharing all that precious information! You help me push forward harder on my ideas!

Collapse
 
heyitslunarojas profile image
Luna Rojas

I like to hear that! Lots of cheers☺

Collapse
 
olgabraginskaya profile image
Olga Braginskaya

This is awesome! Really inspiring—makes me want to try building something too. Thanks for sharing!

Collapse
 
heyitslunarojas profile image
Luna Rojas

Thanks for your words Olga, I'm pretty sure you will make it!🚀

Collapse
 
hadil profile image
Hadil Ben Abdallah

This is amazing 🔥

Collapse
 
heyitslunarojas profile image
Luna Rojas

Thank you very much!

Collapse
 
robin-ivi profile image
Robin Mishra

Appreciate you sharing!

Collapse
 
heyitslunarojas profile image
Luna Rojas

Thanks Robin!☺

Collapse
 
dmotts profile image
Daley Mottley

Very informative! Thanks for sharing 😃👍

Collapse
 
heyitslunarojas profile image
Luna Rojas

Thank you for your time reading Daley!

Collapse
 
maja_moreki_d4f3bac907db2 profile image
Maja Moreki

This very amazing you made history changed the coding world forever.

Collapse
 
heyitslunarojas profile image
Luna Rojas

Glad you enjoyed it☺

Collapse
 
maja_moreki_d4f3bac907db2 profile image
Maja Moreki

📖 can't wait to see how far your development goes

Collapse
 
dragon_horse_8b80c0a8f064 profile image
dragon horse

HELLO TEAM!!!

Collapse
 
heyitslunarojas profile image
Luna Rojas

HELLO!

Collapse
 
dragon_horse_8b80c0a8f064 profile image
dragon horse

Hello. Nice to meet to u.