A place to cache linked articles (think custom and personal wayback machine)
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

index.html 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>The story of a unicorn solo founder making $500,000 ARR (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://www.lunadio.com/blog/the-story-of-a-unicorn-solo-founder-making-dollar500000-arr/">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>The story of a unicorn solo founder making $500,000 ARR</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://www.lunadio.com/blog/the-story-of-a-unicorn-solo-founder-making-dollar500000-arr/" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p>Do what you love, build projects and features people want, and the success will come. I bet you heard that many times. This saying is well known, but I need to point out it takes time to get results. Many founders give up too soon and break their consistency.</p>
  71. <p>It’s not the issue of <a href="https://twitter.com/ivankutskir">Ivan Kuckir</a> and his project <a href="https://www.photopea.com/">Photopea</a>. He has been building this online photo editor for 7 years now, and it’s paying off. Last year, he broke the line of $500,000 ARR, and it’s still growing.</p>
  72. <p>We sat down together with Ivan to discuss his startup journey and how consistency and listening to your customer can get your project over $40k MRR.</p>
  73. <h3 id="hi-ivan-can-you-please-describe-your-project-you-are-working-on">Hi Ivan, can you please describe your project you are working on?</h3>
  74. <p>Hello Lunadio, Photopea is a free web-based graphic software. It’s an alternative to Photoshop and other similar tools. I’ve been working on this project for over 7 years now. It started as an experiment and turned out to be my main source of income.</p>
  75. <h3 id="whats-your-stats-can-you-please-share-some-numbers">What’s your stats? Can you please share some numbers?</h3>
  76. <p>I started to monetize this tool 4 years ago, and it’s growing continuously year by year. Last year, I made over $500k for the first time, and there is still plenty of space to grow for this tool.</p>
  77. <p><img src="https://lh5.googleusercontent.com/CG5I7g7up1BLKO2uEhK-PtvorJzd0HGOt6432yVqAYzray_RMFojueedzIKYsogVLwW4B102pgY7MaVUjyio5y1AkHVk7mANd4wyyrVvTYv8b0wlaOHg8ebtliaIBDZVVomAPO26" alt=""></p>
  78. <h3 id="how-do-you-make-money-from-your-project">How do you make money from your project?</h3>
  79. <p>It might surprise you, but the primary revenue stream is from ads. On top of that, I do license deals. You can customize Photopea using API and integrate it into your projects. I charge a monthly fee for it.</p>
  80. <h3 id="yep-it-is-surprising-for-me-for-sure-why-did-you-decide-to-use-this-type-of-monetization">Yep. It is surprising for me for sure. Why did you decide to use this type of monetization?</h3>
  81. <p>Well, I was building online games before Photopea. Do you remember those flash-based simple online games all around the Internet? I’ve created some of them. Game developers monetized these games by putting banner ads inside. I knew exactly how many views and impressions I need to get decent money out of the project. It is pure math.</p>
  82. <p>Because I have this know-how, I decided to build the tool for free and use ads to monetize.</p>
  83. <h3 id="thats-cool-so-what-are-your-daily-visits-then">That’s cool. So, what are your daily visits then?</h3>
  84. <p>300,000 users come to my website every day. They spend 45,000 hours using my tool each day.</p>
  85. <h3 id="okay-thats-pretty-impressive-i-can-imagine-your-server-costs-are-huge">Okay. That’s pretty impressive. I can imagine your server costs are huge.</h3>
  86. <p>Actually, you won’t believe me, but I pay $45 per year.</p>
  87. <h3 id="are-you-kidding-me">Are you kidding me?!</h3>
  88. <p>It’s all rendered in the user’s browser. There is no database, no backend. I only pay for the hosting of Javascript scripts and static files.</p>
  89. <p><img src="https://lh6.googleusercontent.com/MDBl76C-QhET8u89xLyCGD1wYijyToAzxBrputVypVUwuiCqkgZKtfaabYuc62C1Te-aqHysM445BygdftH4xp5NqH6NT4Xq6bSRyKBvRsQN0TWQ5BVjNSNgAmhEw3uNlFBXjdcL" alt=""></p>
  90. <h3 id="oh-my-let-me-breathe-it-out-thats-amazing-do-you-have-any-other-costs-any-employees-or-still-working-on-the-project-alone">Oh my, let me breathe it out. That’s amazing. Do you have any other costs? Any employees or still working on the project alone?</h3>
  91. <p>I don’t have any employees, and I’m still working on the project alone. In the beginning, I thought it’s a disadvantage. I didn’t want my customer to know I’m the only one working on this. I was afraid of their reaction when they would find out it’s only me using an old $500 notebook.</p>
  92. <p>Later on, I realized I got nothing to hide, and I want to use it as an advantage. I want to show others what they can achieve when they consistently build projects that people want. That’s why I decided to share my story.</p>
  93. <h3 id="and-thank-you-for-that-let-me-take-you-back-a-little-bit-what-was-your-mvp-version-of-photopea-how-did-you-start-this-project">And, thank you for that. Let me take you back a little bit. What was your MVP version of Photopea? How did you start this project?</h3>
  94. <p>It all started as an experiment. I know Photoshop pretty well, and I wanted to find out if it’s possible to parse Photoshop (.psd) files in the website browser. I created a simple web tool where you could open a .psd file, and you were able to download all layers separately. It was a technical challenge, and I like working with new technologies.</p>
  95. <h3 id="compared-to-what-photopea-is-now-you-started-with-a-single-feature-do-you-have-any-advice-for-founders-building-their-products-for-years-before-launching-them">Compared to what Photopea is now, you started with a single feature. Do you have any advice for founders building their products for years before launching them?</h3>
  96. <p>Start with a small product, and add more features on the go. I’ve learned it’s good to launch your projects or features before you are 100% satisfied with that. I still do that now. I’m not trying to do all things perfectly. I launch it as soon as it works, and then I wait for user feedback.</p>
  97. <p>I released a new update supporting .ai (Adobe Illustrator) files, and I know it’s not perfect. However, it works for 80% of users, and others report bugs and all edge cases. Now, I’m going to fix these issues one by one.</p>
  98. <h3 id="when-was-the-time-you-realized-this-could-be-a-successful-project">When was the time you realized this could be a successful project?</h3>
  99. <p>I had like 20 projects back then. All of them had the same importance to me, and my expectations were high for every project. I decided to focus on Photopea because I most enjoyed working on this product. I know I’m building a unique tool, and it motivates me to continue.</p>
  100. <h3 id="how-do-you-prioritize-new-features">How do you prioritize new features?</h3>
  101. <p>Photopea is composed of many small functionalities. Each feature is a new challenge for me, and I’m happy once I finish it.</p>
  102. <p>I receive new feature requests over Github. People are reporting issues and asking for new things there. The funny thing is that 80% of these users created an account on Github the day they posted a new request. I bring many new users to Github over the years. 😅</p>
  103. <p>I choose requests from this list based on my current mood and what I would like to implement next. There is no secret sauce behind it. It’s all about building what people want.</p>
  104. <p><img src="https://lh6.googleusercontent.com/a6eD4iFyY-tgQMX_X1t4QAFNXf7xXkASJI2IrN6S_VYPPa7OT_zWUF2v84EtYfBxww3Sn6kh9uUU2aaV1udHC1gypauOc8Xry_xjlMQxGNep_3H6CNGSoLr2QT5pSlhhHe2OZWtB" alt=""></p>
  105. <h3 id="whats-your-marketing-strategy">What’s your marketing strategy?</h3>
  106. <p>I don’t have any strategy. I’m just building a nice tool people like, and they talk about that. It’s all just word of mouth.</p>
  107. <p><img src="https://lh4.googleusercontent.com/dGiNmdAZXcFQUs13AazmpDk9LnDgHlco0fD5MusNQ79sH7XgZzq_GSXUeYugwCgFpRFEGvnUuEkrTj8U2PwkHqZNaIUbgqc1_1g3Zzt64aaitvsXj4r11COCHTnvat7A-0tKk05u" alt="">
  108. <em>(stats by Ubersuggest)</em></p>
  109. <p>I have no growth hack advice or anything for you. I share new feature updates on Reddit, Twitter, Facebook, sometimes on Hacker News as well.</p>
  110. <p>I launched on Product Hunt a few years ago, and I had absolutely zero results, with no success. Then, some random fan of my tool, with 10 followers, <a href="https://www.producthunt.com/posts/photopea-3">relaunched it</a> last year, and it gets to #4 Product of the Week with more than 1000 upvotes.</p>
  111. <p><img src="https://lh5.googleusercontent.com/C1bj98E_zoHwNIV2s5FXXjSKNDrC7tU2O4MaHgubE9yIwUCqWKNdr9aJ1GfAEqF5WHYwYWqtuwaryoT6wFO7tqOjJR0a7QEsN0x_vgH0eGcitFXHJevICK7rDSEUfgvjMAGnfHkR" alt=""></p>
  112. <h3 id="okay-so-your-advice-would-be-let-someone-else-launch-your-project-on-product-hunt">Okay, so your advice would be, let someone else launch your project on Product Hunt.😅</h3>
  113. <p>Yes, that’s my only marketing advice that worked for me.</p>
  114. <h3 id="can-you-share-any-fuck-up-or-fail">Can you share any fuck up or fail?</h3>
  115. <p>Once, I forgot to update one script, and Photopea didn’t work for like 12 hours. It was during my nighttime. When I woke up and checked my phone, I found 150 emails and approximately 50 tweets reporting my tool doesn’t work. It catapulted me from the bed, and I fixed the issue immediately.</p>
  116. <h3 id="thank-you-very-much-for-the-interview-im-glad-we-know-you-and-your-product-better-i-believe-your-story-is-inspiring-for-all-readers-of-this-blog-post-the-same-way-its-for-me">Thank you very much for the interview. I’m glad we know you and your product better. I believe your story is inspiring for all readers of this blog post the same way it’s for me.</h3>
  117. <h3 id="do-you-have-any-final-advice-for-early-stage-founders">Do you have any final advice for early-stage founders?</h3>
  118. <p>Find a domain you really like and something that you enjoy doing. It’s a long journey.
  119. I love programming and creating new things, and I use it as my superpower. What’s yours?</p>
  120. </article>
  121. <hr>
  122. <footer>
  123. <p>
  124. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  125. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
  126. </svg> Accueil</a> •
  127. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  128. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-rss2"></use>
  129. </svg> Suivre</a> •
  130. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  131. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-user-tie"></use>
  132. </svg> Pro</a> •
  133. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  134. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-mail"></use>
  135. </svg> Email</a> •
  136. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  137. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-hammer2"></use>
  138. </svg> Légal</abbr>
  139. </p>
  140. <template id="theme-selector">
  141. <form>
  142. <fieldset>
  143. <legend><svg class="icon icon-brightness-contrast">
  144. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-brightness-contrast"></use>
  145. </svg> Thème</legend>
  146. <label>
  147. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  148. </label>
  149. <label>
  150. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  151. </label>
  152. <label>
  153. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  154. </label>
  155. </fieldset>
  156. </form>
  157. </template>
  158. </footer>
  159. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  160. <script>
  161. function loadThemeForm(templateName) {
  162. const themeSelectorTemplate = document.querySelector(templateName)
  163. const form = themeSelectorTemplate.content.firstElementChild
  164. themeSelectorTemplate.replaceWith(form)
  165. form.addEventListener('change', (e) => {
  166. const chosenColorScheme = e.target.value
  167. localStorage.setItem('theme', chosenColorScheme)
  168. toggleTheme(chosenColorScheme)
  169. })
  170. const selectedTheme = localStorage.getItem('theme')
  171. if (selectedTheme && selectedTheme !== 'undefined') {
  172. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  173. }
  174. }
  175. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  176. window.addEventListener('load', () => {
  177. let hasDarkRules = false
  178. for (const styleSheet of Array.from(document.styleSheets)) {
  179. let mediaRules = []
  180. for (const cssRule of styleSheet.cssRules) {
  181. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  182. continue
  183. }
  184. // WARNING: Safari does not have/supports `conditionText`.
  185. if (cssRule.conditionText) {
  186. if (cssRule.conditionText !== prefersColorSchemeDark) {
  187. continue
  188. }
  189. } else {
  190. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  191. continue
  192. }
  193. }
  194. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  195. }
  196. // WARNING: do not try to insert a Rule to a styleSheet you are
  197. // currently iterating on, otherwise the browser will be stuck
  198. // in a infinite loop…
  199. for (const mediaRule of mediaRules) {
  200. styleSheet.insertRule(mediaRule.cssText)
  201. hasDarkRules = true
  202. }
  203. }
  204. if (hasDarkRules) {
  205. loadThemeForm('#theme-selector')
  206. }
  207. })
  208. </script>
  209. </body>
  210. </html>