<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[KW Codes]]></title><description><![CDATA[Hi 👋 Krzysztof here. I write about iOS development and building online products.]]></description><link>https://kwcodes.com/</link><image><url>https://kwcodes.com/favicon.png</url><title>KW Codes</title><link>https://kwcodes.com/</link></image><generator>Ghost 5.57</generator><lastBuildDate>Wed, 15 Apr 2026 14:27:10 GMT</lastBuildDate><atom:link href="https://kwcodes.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[How to find a remote job when you're an iOS/Android developer from Europe]]></title><description><![CDATA[<p>Getting a new remote job in tech is tough. Especially when you don&apos;t live in the United States. There are a lot of companies that are not willing to hire candidates from Europe.</p><p>When you apply for a job, you need to make sure, that the company is</p>]]></description><link>https://kwcodes.com/how-to-find-a-remote-job-when-youre-an-ios-android-developer-from-europe/</link><guid isPermaLink="false">618d3290879372050fb6ecf7</guid><dc:creator><![CDATA[Krzysztof]]></dc:creator><pubDate>Sun, 14 Nov 2021 17:19:09 GMT</pubDate><content:encoded><![CDATA[<p>Getting a new remote job in tech is tough. Especially when you don&apos;t live in the United States. There are a lot of companies that are not willing to hire candidates from Europe.</p><p>When you apply for a job, you need to make sure, that the company is OK hiring an engineer from your country. Do it as early as possible. If you don&apos;t, you may be disappointed one day.</p><p>It happened to me once. I was in the recruitment process, got positive feedback and I was informed that I passed to the next step. Unfortunately before receiving the next task, the company let me know that they changed their mind. They decided to not hire anyone from Europe. </p><p>Alright, let&apos;s go back to the main point: where to look for your next remote job as a mobile engineer? </p><h2 id="job-boards">Job boards</h2><p>Unfortunately, none of the job boards is perfect. Sometimes they make life easy and have basic filters like <code>EMEA</code> or <code>Worldwide</code>. But usually, you need to make your own research if the company is fine hiring remote software engineers within the EMEA timezones. Here are the recommended job boards:</p><!--kg-card-begin: markdown--><ul>
<li><a href="https://remotehunt.com/?ref=kwcodes.com">https://remotehunt.com</a></li>
<li><a href="https://angel.co/jobs?ref=kwcodes.com">https://angel.co/jobs</a></li>
<li><a href="https://startup.jobs/?ref=kwcodes.com">https://startup.jobs</a></li>
<li><a href="https://justjoin.it/?ref=kwcodes.com">https://justjoin.it</a></li>
<li><a href="https://nofluffjobs.com/?ref=kwcodes.com">https://nofluffjobs.com/</a></li>
<li><a href="https://pragmatic-engineer.pallet.xyz/jobs?ref=kwcodes.com">https://pragmatic-engineer.pallet.xyz/jobs</a></li>
</ul>
<!--kg-card-end: markdown--><h2 id="hacker-newswho-is-hiring">Hacker News - Who is hiring</h2><p>Every month on Hacker News there&apos;s <em><strong>Ask HN: Who is hiring?</strong></em> thread. A lot of companies all over the world put their current job openings. There are tools created to make searching easier like <a href="https://kennytilton.github.io/whoishiring/?ref=kwcodes.com" rel="nofollow">https://kennytilton.github.io/whoishiring/</a>. You can filter job offers by including keywords like <code>remote</code>, <code>iOS</code>, <code>Android</code>, <code>mobile</code> and excluding <code>US only</code></p><p>Here&apos;s a sample thread: <a href="https://news.ycombinator.com/item?id=29067493&amp;ref=kwcodes.com">https://news.ycombinator.com/item?id=29067493</a></p><h2 id="twitter">Twitter</h2><p>Another good way of finding a job offer early is to search for it on Twitter. You can search for <code>hiring iOS</code>, <code>hiring Android</code>, <code>remote iOS job</code>, <code>remote Android job</code> or any other job-related keyword. &#xA0;I recommend searching for it on Tweet Deck as it makes a job easier: <a href="https://tweetdeck.twitter.com/?ref=kwcodes.com">https://tweetdeck.twitter.com</a>.</p><h2 id="linkedin">LinkedIn</h2><p>Here you got two options. First, you can search for the proper keywords. Another one is to reach out to recruiters directly. Try to find recruiters that specialize in mobile recruitment.</p><h2 id="use-the-curated-list-of-companies">Use the curated list of companies</h2><p>Searching for the current openings and filtering companies based on their openness for remote mobile engineers from EMEA/Europe is time-consuming. If you don&apos;t want to spend many hours on it, I got something for you.</p><p>I curated 90+ remote companies that hire mobile developers from Europe. &#xA0;Get it below &#x1F447; </p><!--kg-card-begin: html--><script src="https://gumroad.com/js/gumroad-embed.js"></script>
<div class="gumroad-product-embed" data-outbound-embed="true"><a href="https://gumroad.com/l/tfGja?ref=kwcodes.com">Loading...</a></div><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[How I failed 5 side projects in 6 years, earning $0]]></title><description><![CDATA[<p>This is a story about me dreaming of building an online project that generates revenue, seeking financial independence and creative freedom. After five years and no success, it&apos;s still a dream. Let me tell you more about my failed projects.</p><h1 id="planetoid-2015-2016">Planetoid (2015-2016)</h1><p>It&apos;s all started with</p>]]></description><link>https://kwcodes.com/how-i-failed-5-side-projects-in-6-years-earning-0/</link><guid isPermaLink="false">610ea290eb2f6f1acf7e2b43</guid><dc:creator><![CDATA[Krzysztof]]></dc:creator><pubDate>Fri, 22 Oct 2021 19:09:41 GMT</pubDate><content:encoded><![CDATA[<p>This is a story about me dreaming of building an online project that generates revenue, seeking financial independence and creative freedom. After five years and no success, it&apos;s still a dream. Let me tell you more about my failed projects.</p><h1 id="planetoid-2015-2016">Planetoid (2015-2016)</h1><p>It&apos;s all started with a game. Who doesn&apos;t love those, right? Imagine building one yourself! It would be so amazing!</p><p>Back in 2015, I paired with my friend and we decided to create a mobile game for iOS: Planetoid. In a nutshell, it was a graph-based strategy where you had to conquer all the planets by shooting bullets. Here&apos;s the video of how it looked:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/IJVSyolxm7A?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>We spent more than one year building it after work and over the weekends. Everything was done by us: design, music, level design, etc. We finally released it in November 2016 as a paid app. Unfortunately, people weren&apos;t interested in paying for it. 2 months resulted in no sales.</p><p>What&apos;s another way to monetize an app? Yes: ads. We decided to integrate ads and publish the game for free. After a few months, we got 300 installations. It was a cold bucket of water.</p><p>We spent so much time on the game and almost no one played it.</p><p>But hey, it was our first experience! We learned a lot, made good and bad decisions on the way.</p><ul><li>We gained experience in building an app from scratch and publishing it on the App Store. It was really valuable skills taking into account I had started my professional career as an iOS developer</li><li>The game was written in Objective-C using SpriteKit. It was the time when Swift was changing dramatically every release and it was a great idea to code in Obj-C. We saved a ton of time on code migration to newer Swift versions.</li><li>The marketing was almost non-existential. We posted about the game in common places like Reddit or Hacker News and we hoped that App Store would do the job. But it didn&apos;t. Planetoid simply drowned in the App Store.</li></ul><h1 id="minfinitya-minimal-time-tracker-2017">Minfinity - a minimal time tracker (2017)</h1><figure class="kg-card kg-image-card"><img src="https://kwcodes.com/content/images/2021/10/minfinity@2x.png" class="kg-image" alt loading="lazy" width="912" height="768" srcset="https://kwcodes.com/content/images/size/w600/2021/10/minfinity@2x.png 600w, https://kwcodes.com/content/images/2021/10/minfinity@2x.png 912w" sizes="(min-width: 720px) 720px"></figure><p>I was disappointed with the outcome from Planetoid and decided to tackle the next project in another way.</p><p>This time I planned to build a time tracking macOS app. I designed it first in Zeplin. Then created a landing page with a mailing list for my next app. I wanted to promote it and verify if the will be people willing to join the mailing list. I integrated Google Analytics to see if anyone visits the website. I also set up a small campaign in Google Ads.</p><p>After 3 months of a campaign and marketing, I got 5 people who subscribed to the mailing list. It was below my expectations and I abandoned the project.</p><h1 id="minimal-metronome-2017">Minimal Metronome (2017)</h1><p>This time, I wanted to build something just for myself.</p><p>One of my hobbies is playing the guitar. I wanted to build a metronome app that was minimal and functional. The idea was to have the smallest amount of buttons and to control the app by swiping gestures and getting haptic feedback on every change.</p><p>Unfortunately, here the motivation didn&apos;t last too long. I was a bit tired after the last few projects. What&apos;s more, I found the app on the App Store that fulfilled my needs. So I abandoned this project as well.</p><figure class="kg-card kg-image-card"><img src="https://kwcodes.com/content/images/2021/10/minmal-metronome-3.jpeg" class="kg-image" alt="minmal-metronome-3" loading="lazy"></figure><h1 id="a-long-almost-2-year-break">A long, almost 2-year break</h1><p>After these projects, I was exhausted. I couldn&apos;t enjoy working on side projects anymore.</p><p>Having a day job and working on side projects is tough. It can burn you down. And it hit me a bit as well. I needed a break.</p><p>It was time to recharge my batteries and return to indie hacking only when I&apos;ll be sure I&apos;ll enjoy it. And it took almost 2 years.</p><h1 id="the-returnseptember-2019">The return - September 2019</h1><p>Here we go again. September 2019. It took some time to take a rest, but it was worth it. I was excited about side projects again.</p><p>In late 2019 I was investigating the real estate market. The problem is that there are a lot of places where you can search for an apartment. What&apos;s more, the market was so hot, it was impossible to buy an apartment from the secondary market. Great deals were gone literally in hours.</p><p>I wanted to develop a tool to monitor new offers and notify me if there is an interesting one. The plan was to provide parameters like price, space, district, keywords, etc, and based on them send a notification.</p><p>Another project just for me with some potential for monetization.</p><p>I started developing scrapers gathering data. I spent maybe 2 weeks on it when I realized the level of complexity. This was too much work for just one person.</p><p>After a quick search on the Internet, I decided to purchase one of the existing tools and I abandoned the project. I didn&#x2019;t want to burn out again.</p><p>Next time: choose something simple that can be accomplished by one person.</p><h1 id="get-a-product-job-may-2020may-2021">Get a Product Job (May 2020 - May 2021)</h1><p>This time the main objective was to learn something new by doing. I chose Ruby on Rails. It&apos;s a great framework to build websites quickly. What&#x2019;s more, I wanted to improve my web development skills. After this project, I wanted to have another tool under my belt for any future ideas.</p><p>I started building yet another job board. This time I planned to create a website with job offers only from product-based IT companies. &#xA0;I spent 6 months building it in my free time after work. I launched it in October 2020.</p><figure class="kg-card kg-image-card"><img src="https://kwcodes.com/content/images/2021/10/get-a-product-job.png" class="kg-image" alt loading="lazy" width="2000" height="1464" srcset="https://kwcodes.com/content/images/size/w600/2021/10/get-a-product-job.png 600w, https://kwcodes.com/content/images/size/w1000/2021/10/get-a-product-job.png 1000w, https://kwcodes.com/content/images/size/w1600/2021/10/get-a-product-job.png 1600w, https://kwcodes.com/content/images/2021/10/get-a-product-job.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>I did some basic marketing. I was reaching out to companies on LinkedIn. I was posting in regular places like Reddit or Hacker News. After few weeks I managed to get one job posting from one of the companies. The rest of the offers I scraped and curated from different sources.</p><p>It&#x2019;s worth mentioning that posting a job post was for free. I found out how dealing with taxes might be troublesome and I decided to make a website for free until I get a significant number of job postings.</p><p>Unfortunately, the website didn&#x2019;t get any traction and I killed it in May 2021. But the goal of the project was accomplished:</p><ul><li>I learned the basics of Ruby on Rails, Renderer and improved my skills in front-end development.</li><li>I learned about different ways of accepting payments.</li><li>I learned how to handle taxes for side projects when you&#x2019;re an EU citizen.</li></ul><h1 id="takeaways">Takeaways</h1><p>After all these projects I learned a lot about myself and what motivates me (or not).<br>I still got many ideas in my head but right now I&#x2019;m more cautious about choosing my next project.</p><p>First of all, when deciding about the next project, I need to choose the smallest idea possible that can be developed by one person. Cut the scope as much as possible.</p><p>Estimate the time needed for the MVP. It shouldn&#x2019;t take more than 3 weeks, assuming having a day job and working on the project only in my free time. If the estimation is higher, try to find out the quickest way to develop the MVP. There are many no-code tools that might speed up the development. Just looks what Samuel Thompson was able to create in one day! </p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Had a business idea that I think could build in 24 hours and get to $5,000 MRR in 30 days&#x2026;<br><br>Should I write a massive thread outlining my entire process?<br><br>- Building MVP in 1 night<br>- Initial Market Research<br>- Organic Marketing<br>- Paid Ads Testing<br><br>Would be a wild experiment&#x2026;</p>&#x2014; Samuel Thompson &#x1F97D; (@ImSamThompson) <a href="https://twitter.com/ImSamThompson/status/1449518979387576323?ref_src=twsrc%5Etfw&amp;ref=kwcodes.com">October 16, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>Having an increasing number of users is super motivating. Try to release the project as fast as possible to get first feedback and an early dose of fresh motivation.</p><p>And that&#x2019;s all. These were all my failed projects. Keep fingers crossed for the next one.</p><p>If you want to follow my journey on earning first $ from side projects, follow me on Twitter:</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">How I failed 5 side projects in 6 years, earning $0.<br><br>That&apos;s the latest blog post summarizing my bootstrapping history.<a href="https://t.co/OCD8D6kOeb?ref=kwcodes.com">https://t.co/OCD8D6kOeb</a><a href="https://twitter.com/hashtag/buildinpublic?src=hash&amp;ref_src=twsrc%5Etfw&amp;ref=kwcodes.com">#buildinpublic</a></p>&#x2014; Krzysztof (@kwcodes) <a href="https://twitter.com/kwcodes/status/1452337752289251333?ref_src=twsrc%5Etfw&amp;ref=kwcodes.com">October 24, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure>]]></content:encoded></item><item><title><![CDATA[Monetizing side projects as an EU citizen. Accepting payments without worrying about taxes.]]></title><description><![CDATA[<p>You got a new idea for your side project. You spend few weeks on the implementation working in your free time after work. Right now you want to integrate a payment system but you realize about this mysterious topic: taxes. You start reading about it and you find out about</p>]]></description><link>https://kwcodes.com/monetizing-side-projects-as-an-eu-citizen/</link><guid isPermaLink="false">60fdc107bf21a37777e7da99</guid><dc:creator><![CDATA[Krzysztof]]></dc:creator><pubDate>Thu, 29 Jul 2021 11:52:24 GMT</pubDate><content:encoded><![CDATA[<p>You got a new idea for your side project. You spend few weeks on the implementation working in your free time after work. Right now you want to integrate a payment system but you realize about this mysterious topic: taxes. You start reading about it and you find out about VAT, GST, different rates depending on multiple conditions. What&apos;s more, you&apos;re a European Union citizen - VAT MOSS and your country&apos;s regulations don&apos;t make things simpler... But you wanted to focus on the product, not on taxes!</p><p>I&apos;ve been in that place. That&apos;s why I abandoned one of the recent projects. If I had known about handling taxes in the EU a bit earlier, probably I would have chosen a different idea.</p><p>Defining a monetization strategy is a crucial step when you plan your next side business. Being able to earn money while not spending a ton of time on taxes and bureaucracy is invaluable. Dealing with all the paperwork can kill your inspiration. </p><p>That&apos;s why I wanted to list out the payment providers that can help you with taxes so you can focus on your product.</p><h2 id="merchants-of-records">Merchants of Records</h2><p>A merchant of record is an entity that sells goods or services on your behalf. It handles all the various taxes for you. You don&apos;t need to worry about different VAT taxes, rates, and so on. If you earn money, it pays you out on regular basis (i.e. once per week) and you only need to handle income tax on your own. </p><p>Here&apos;s a nice explanation <a href="https://paddle.com/blog/what-is-merchant-of-record/?ref=kwcodes.com">https://paddle.com/blog/what-is-merchant-of-record/</a></p><blockquote>&#x26A0;&#xFE0F; If you decide to use a Merchant of Records, remember to check if the type of your business is supported! For example, various human services (like consultations) are not welcomed.</blockquote><h3 id="gumroad">Gumroad</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://gumroad.com/?ref=kwcodes.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Gumroad | Sell Digital Products &amp; Memberships</div><div class="kg-bookmark-description">Gumroad makes it easy for you to sell digital products, memberships and more. Join the creator economy and escape your 9-5 desk job.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://assets.website-files.com/img/webclip.png" alt><span class="kg-bookmark-author">Gumroad Logo</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://assets.website-files.com/609bfbe57ec8f3547d866cd7/60b677f0e28db421c1b9a931_gumroad-default-og.png" alt></div></a></figure><ul><li>What you can sell on Gumroad <a href="https://help.gumroad.com/category/232-what-you-can-sell-on-gumroad?ref=kwcodes.com">https://help.gumroad.com/category/232-what-you-can-sell-on-gumroad</a></li><li>Dealing with VAT <a href="https://help.gumroad.com/article/10-dealing-with-vat?ref=kwcodes.com">https://help.gumroad.com/article/10-dealing-with-vat</a></li></ul><h3 id="paddle">Paddle</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://paddle.com/?ref=kwcodes.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Paddle - Revenue Delivery Platform for SaaS</div><div class="kg-bookmark-description">Helping B2B &amp; B2C SaaS increase global conversions, reduce churn, stay compliant, and scale up fast</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://paddle.com/assets/images/favicons/apple-touch-icon.png" alt><span class="kg-bookmark-author">Revenue Delivery Platform for SaaSicon-angelicon-emailicon-facebookicon-linkedinicon-slackicon-twitterGroup 4Page 1Page 1</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://d33wubrfki0l68.cloudfront.net/d44ced5032e91f413d47138a1f9107f2b3a90543/da230/assets/svg/logo-primary.svg" alt></div></a></figure><ul><li>Not supported types of businesses <a href="https://paddle.com/support/aup/?ref=kwcodes.com">https://paddle.com/support/aup/</a></li><li>How Paddle handles VAT on your behalf <a href="https://paddle.com/support/how-does-paddle-handle-vat-on-my-behalf/?ref=kwcodes.com">https://paddle.com/support/how-does-paddle-handle-vat-on-my-behalf/</a></li></ul><h3 id="lemon-squeezy">Lemon Squeezy</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.lemonsqueezy.com/?ref=kwcodes.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Lemon Squeezy: Sell digital products the easy-peasy way</div><div class="kg-bookmark-description">Selling digital downloads, subscriptions, and software licenses has never been easier, faster, or more secure.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.lemonsqueezy.com/wp-content/themes/lemonsqueezy/images/ls-logo.png" alt><span class="kg-bookmark-author">Lemon Squeezy: Sell digital products the easy-peasy way</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.lemonsqueezy.com/wp-content/themes/lemonsqueezy/images/meta-image.jpg" alt></div></a></figure><ul><li>A brand new solution on the market.</li><li>Sales Tax &amp; VAT <a href="https://docs.lemonsqueezy.com/article/57-sales-tax-vat?ref=kwcodes.com">https://docs.lemonsqueezy.com/article/57-sales-tax-vat</a></li></ul><h2 id="payment-service-provider">Payment Service Provider</h2><p>Payment Service Provider offers services for accepting payments by various methods. In comparison to Merchant of Records, it handles only the whole transaction process.</p><h3 id="stripe">Stripe</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://stripe.com/docs/tax?ref=kwcodes.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Stripe Tax</div><div class="kg-bookmark-description">Calculate and collect sales tax, VAT, and GST with one line of code or the click of a button.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://b.stripecdn.com/docs/assets/6bf407479706b31fa82c548be63edc52.png" alt></div></div><div class="kg-bookmark-thumbnail"><img src="https://b.stripecdn.com/docs/assets/checkout.99472b5fe8d0d06e3f7d3706eb498068.png" alt></div></a></figure><ul><li>Released recently Stripe Tax <a href="https://stripe.com/docs/tax?ref=kwcodes.com">https://stripe.com/docs/tax</a>. Now it&apos;s possible to calculate and collect sales taxes, VAT, GST automatically. Previously as an EU citizen, you had to calculate it on your own which made Stripe not the best choice for EU-based indie hackers.</li><li>You still need an accountant to help with any tax payments.</li><li>Supports a lot more business types than Merchants of Records. A list of restricted businesses <a href="https://stripe.com/en-pl/restricted-businesses?ref=kwcodes.com">https://stripe.com/en-pl/restricted-businesses</a></li></ul><h2 id="marketplaces">Marketplaces</h2><h3 id="apple-app-store">Apple App Store</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://developer.apple.com/app-store/?ref=kwcodes.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">App Store - Apple Developer</div><div class="kg-bookmark-description">Attract and engage over a billion App Store customers from around the world. Our useful tools and strategies are designed to make your app business successful.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://developer.apple.com/favicon.ico" alt><span class="kg-bookmark-author">Apple Developer</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://developer.apple.com/news/images/og/app-store-og.png" alt></div></a></figure><ul><li>Handles all the taxes for you (similar to Merchant of Records) in return for the 30% commission rate.</li><li>There is a Small Business Program with a 15% commission rate <a href="https://developer.apple.com/app-store/small-business-program/?ref=kwcodes.com">https://developer.apple.com/app-store/small-business-program/</a></li></ul><h3 id="google-play">Google Play</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://developer.android.com/distribute/google-play/?ref=kwcodes.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Google Play Store | Android Developers</div><div class="kg-bookmark-description">&lt;!-- hide description --&gt;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.gstatic.com/devrel-devsite/prod/v854c54f3442b5b06d97cb2bf43f3647f489796c80c33899ecd29b91ae5303388/android/images/touchicon-180.png" alt><span class="kg-bookmark-author">Android Developers</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://developer.android.com/images/distribute/play-store-hero_rec.png" alt></div></a></figure><h2 id="final-words">Final words</h2><p>I hope that helps a bit. If you know about any other solution, please let me know. You can find me on Twitter <a href="https://twitter.com/kwcodes?ref=kwcodes.com">https://twitter.com/kwcodes</a>.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Monetizing side projects is hard. Especially if you live in the EU. Spend 5 minutes reading about VAT, VAT MOSS, GST and you&#x2019;ll get an instant headache.<br> <br>Here&#x2019;s the list of solutions to use so you can focus on your product and not worry about taxes: <br><br>&#x1F447;</p>&#x2014; Krzysztof (@kwcodes) <a href="https://twitter.com/kwcodes/status/1420771554204524553?ref_src=twsrc%5Etfw&amp;ref=kwcodes.com">July 29, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure>]]></content:encoded></item><item><title><![CDATA[Schedule background jobs in Rails with Integromat]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>The most common tool for background jobs in Ruby on Rails is Sidekiq. Unfortunately, it&apos;s not standalone and it has Redis as a dependency. In this post, I will present an alternative approach for scheduling tasks in Rails.</p>
<blockquote>
<p>Oh come on! What&apos;s the problem with Sidekiq?</p></blockquote>]]></description><link>https://kwcodes.com/schedule-background-jobs-in-rails-with-integromat/</link><guid isPermaLink="false">602827a52bcd4604cf1d03e0</guid><dc:creator><![CDATA[Krzysztof]]></dc:creator><pubDate>Sat, 13 Feb 2021 21:01:16 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>The most common tool for background jobs in Ruby on Rails is Sidekiq. Unfortunately, it&apos;s not standalone and it has Redis as a dependency. In this post, I will present an alternative approach for scheduling tasks in Rails.</p>
<blockquote>
<p>Oh come on! What&apos;s the problem with Sidekiq? It&apos;s well tested and widely used in many production apps!</p>
</blockquote>
<p>Please remember that I focus on product bootstrapping. Time to market is crucial. I&apos;m also a one-man army and I try to minimize any unneeded maintenance.</p>
<p>To be able to use Sidekiq you need to set up and maintain a new service with Redis. It takes time and effort. I was looking for a solution to quickly implement scheduled jobs without any overhead for my Rails app: <a href="https://getaproductjob.com/?ref=kwcodes">Get a Product Job</a>.</p>
<blockquote>
<p>Fine, why cannot you just use cron?</p>
</blockquote>
<p>I&apos;m using <a href="https://render.com/?ref=kwcodes.com">Render</a> and its services don&apos;t have cron out of the box.</p>
<h2 id="solution">Solution</h2>
<p>I decided to use <a href="https://www.integromat.com/?pc=kwcodes&amp;ref=kwcodes.com">Integromat</a>. It&apos;s a tool for automating processes and it has an attractive free tier (1000 operations/month). Just enough for small side projects.</p>
<p>How to glue it with the Ruby on Rails app?</p>
<ol>
<li>Create a new controller with an action containing your task in <code>app/controllers/background_jobs_controller.rb</code>:</li>
</ol>
<pre><code class="language-ruby">class BackgroundJobsController &lt; ApplicationController
  def cleanup
    async_rake &quot;background:cleanup&quot;
	# you can also pass environment variables as follows:
    # async_rake &quot;background:cleanup&quot;, :dry_run =&gt; &quot;false&quot;
    head :ok
  end
end
</code></pre>
<ol start="2">
<li>Define a method to execute rake tasks asynchronously in <code>app/controllers/application_controller.rb</code>.</li>
</ol>
<pre><code class="language-ruby">def async_rake(task, options = {})
  options[:rails_env] ||= Rails.env

  env_vars = options.map { |key, value| &quot;#{key.to_s.upcase}=&apos;#{value.to_s}&apos;&quot; }
  env_vars_string = env_vars.join(&apos; &apos;)

  log_file = File.join(Rails.root, &quot;log/async_rake.#{Rails.env}.log&quot;)

  Process.fork {
    exec(&quot;#{env_vars_string} bin/rake #{task} --trace 2&gt;&amp;1 &gt;&gt; #{log_file}&quot;)
  }
end
</code></pre>
<p>Implementation from <a href="https://gist.github.com/tompave/ae53fbab32ebebf1072e?ref=kwcodes.com">https://gist.github.com/tompave/ae53fbab32ebebf1072e</a></p>
<ol start="3">
<li>Create a rake task <code>lib/tasks/background.rake</code> to perform any background logic you need:</li>
</ol>
<pre><code class="language-ruby">namespace :background do
  task :cleanup =&gt; :environment do
    puts &quot;&#x1F44B; from the background task!&quot;
  end
end
</code></pre>
<ol start="4">
<li>Add a new route in config/routes.rb</li>
</ol>
<pre><code class="language-ruby">post &apos;/task/cleanup&apos;, to: &apos;background_jobs#cleanup&apos;
</code></pre>
<ol start="5">
<li>
<p>Go to <a href="https://www.integromat.com/?pc=kwcodes&amp;ref=kwcodes.com">Integromat</a> and create a new scenario.<br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.34.08-1.png" alt="Screenshot-2021-02-13-at-19.34.08-1" loading="lazy"></p>
</li>
<li>
<p>Select <strong>HTTP</strong> and click click <strong>Continue</strong>.<br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.34.31-1.png" alt="Screenshot-2021-02-13-at-19.34.31-1" loading="lazy"></p>
</li>
<li>
<p>Click on <strong>HTTP</strong> and select <strong>Make a request</strong>.<br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.39.33-1.png" alt="Screenshot-2021-02-13-at-19.39.33-1" loading="lazy"><br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.39.44-2.png" alt="Screenshot-2021-02-13-at-19.39.44-2" loading="lazy"></p>
</li>
<li>
<p>Configure <a href="https://www.integromat.com/?pc=kwcodes&amp;ref=kwcodes.com">Integromat</a> to make a request to <code>/task/cleanup</code> endpoint you just set up in the Rails app.<br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.45.56-1.png" alt="Screenshot-2021-02-13-at-19.45.56-1" loading="lazy"></p>
</li>
<li>
<p>After saving a request click on a clock icon to configure when to send a request.<br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.44.11-1.png" alt="Screenshot-2021-02-13-at-19.44.11-1" loading="lazy"></p>
</li>
<li>
<p>Set up when to fire your background task.<br>
<img src="https://kwcodes.com/content/images/2021/02/Screenshot-2021-02-13-at-19.44.17-1.png" alt="Screenshot-2021-02-13-at-19.44.17-1" loading="lazy"></p>
</li>
<li>
<p>Save the scenario and that&apos;s all! You can run it once to test the whole setup.</p>
</li>
</ol>
<h2 id="summary">Summary</h2>
<p>What are the pros and cons of this approach?<br>
&#x2705; Quick implementation.<br>
&#x2705; No new layers to maintain (Redis + Sidekiq).<br>
&#x2705; Money saved on new services (quite important when you&apos;re just starting out and validating ideas).</p>
<p>&#x1F6A8; Not the safest solution. You might consider adding authorization or at least server-side checks to make sure that the task is not run too often.<br>
&#x1F6A8; For some of you, Integromat free tier might not be enough.<br>
&#x1F6A8; If not careful, you can easily exceed Integromat&apos;s free tier.</p>
<!--kg-card-end: markdown--><hr><!--kg-card-begin: html-->
<link rel="stylesheet" href="https://emailoctopus.com/bundles/emailoctopuslist/css/1.6/form.css">

<style>
.center {
  margin: auto;
  width: 50%;
}
</style>

<div class="center emailoctopus-form-wrapper emailoctopus-form-centered null" style="font-family: Arial, &quot;Helvetica Neue&quot;, Helvetica, sans-serif; color: rgb(26, 26, 26);">
  <h2 class="emailoctopus-heading">
    Follow my journey trying to bootstrap a side business.
  </h2>
  <p class="emailoctopus-success-message" style="color: var(--darker-gray-color);">
  </p>
  <p class="emailoctopus-error-message" style="color: var(--darker-gray-color);">
  </p>
  <form action="https://emailoctopus.com/lists/a03126b0-6b14-11eb-a3d0-06b4694bee2a/members/embedded/1.3s/add" method="post" data-message-success="Thanks for subscribing! Please check your email to confirm." data-message-missing-email-address="Your email address is required." data-message-invalid-email-address="Your email address looks incorrect, please try again." data-message-bot-submission-error="This doesn&apos;t look like a human submission." data-message-consent-required="Please check the checkbox to indicate your consent." data-message-invalid-parameters-error="This form has missing or invalid fields." data-message-unknown-error="Sorry, an unknown error has occurred. Please try again later." class="emailoctopus-form" data-sitekey="6LdYsmsUAAAAAPXVTt-ovRsPIJ_IVhvYBBhGvRV6">
    <div class="emailoctopus-form-row">
      <label for="field_0">
        Email address
      </label>
      <input id="field_0" name="field_0" type="email" placeholder required="required">
    </div>
    <div aria-hidden="true" class="emailoctopus-form-row-hp">
      <input type="text" name="hpc4b27b6e-eb38-11e9-be00-06b4694bee2a" tabindex="-1" autocomplete="nope">
    </div>
    <div class="emailoctopus-form-row-subscribe">
      <input type="hidden" name="successRedirectUrl">
      <button type="submit" style="color: rgb(51, 51, 51); font-family: inherit; background-color: rgb(255, 87, 47);">
        Subscribe
      </button>
    </div>
  </form>
  <div class="emailoctopus-rewards" style="color: var(--darker-gray-color);">
    Powered by
    <a href="https://emailoctopus.com/?urli=5mTcC&amp;utm_medium=user_referral&amp;utm_source=builder" target="_blank">
      EmailOctopus
    </a>
  </div>
</div>
    
<script src="https://emailoctopus.com/bundles/emailoctopuslist/js/1.6/form-recaptcha.js">
</script>
<script src="https://emailoctopus.com/bundles/emailoctopuslist/js/1.6/form-embed.js">
</script>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[How to store credentials and secrets in Ruby on Rails 6]]></title><description><![CDATA[<p>Ruby on Rails has a support for storing credentials and secrets with <code>rails credentials:edit</code></p><ul><li>Rails 5.1 introduced <code>secrets</code> <a href="https://github.com/rails/rails/pull/28038?ref=kwcodes.com">https://github.com/rails/rails/pull/28038</a></li><li>Rails 5.2 replaced <code>secrets</code> with <code>credentials</code> <a href="https://github.com/rails/rails/pull/30067?ref=kwcodes.com">https://github.com/rails/rails/pull/30067</a></li><li>Rails 6. added support for multi environment credentials <a href="https://github.com/rails/rails/pull/33521?ref=kwcodes.com">https:</a></li></ul>]]></description><link>https://kwcodes.com/how-to-store-credentials-and-secrets-in-ruby-on-rails-6/</link><guid isPermaLink="false">60243bb52bcd4604cf1d01b2</guid><category><![CDATA[Rails Tips]]></category><dc:creator><![CDATA[Krzysztof]]></dc:creator><pubDate>Wed, 10 Feb 2021 20:38:27 GMT</pubDate><content:encoded><![CDATA[<p>Ruby on Rails has a support for storing credentials and secrets with <code>rails credentials:edit</code></p><ul><li>Rails 5.1 introduced <code>secrets</code> <a href="https://github.com/rails/rails/pull/28038?ref=kwcodes.com">https://github.com/rails/rails/pull/28038</a></li><li>Rails 5.2 replaced <code>secrets</code> with <code>credentials</code> <a href="https://github.com/rails/rails/pull/30067?ref=kwcodes.com">https://github.com/rails/rails/pull/30067</a></li><li>Rails 6. added support for multi environment credentials <a href="https://github.com/rails/rails/pull/33521?ref=kwcodes.com">https://github.com/rails/rails/pull/33521</a></li></ul><pre><code class="language-shell">export EDITOR=&quot;code --wait&quot; # or export EDITOR=vim
# Create global credentials at config/credentials.yml.enc and config/master.key
rails credentials:edit
 
# Create credentials for a given environment at config/credentials/&lt;environment&gt;.yml.enc
# It takes precedence over global credentials
rails credentials:edit --environment production
rails credentials:edit --environment development</code></pre><hr><!--kg-card-begin: html-->
<link rel="stylesheet" href="https://emailoctopus.com/bundles/emailoctopuslist/css/1.6/form.css">

<style>
.center {
  margin: auto;
  width: 50%;
}
</style>

<div class="center emailoctopus-form-wrapper emailoctopus-form-centered null" style="font-family: Arial, &quot;Helvetica Neue&quot;, Helvetica, sans-serif; color: rgb(26, 26, 26);">
  <h2 class="emailoctopus-heading">
    Follow my journey trying to bootstrap a side business.
  </h2>
  <p class="emailoctopus-success-message" style="color: var(--darker-gray-color);">
  </p>
  <p class="emailoctopus-error-message" style="color: var(--darker-gray-color);">
  </p>
  <form action="https://emailoctopus.com/lists/a03126b0-6b14-11eb-a3d0-06b4694bee2a/members/embedded/1.3s/add" method="post" data-message-success="Thanks for subscribing! Please check your email to confirm." data-message-missing-email-address="Your email address is required." data-message-invalid-email-address="Your email address looks incorrect, please try again." data-message-bot-submission-error="This doesn&apos;t look like a human submission." data-message-consent-required="Please check the checkbox to indicate your consent." data-message-invalid-parameters-error="This form has missing or invalid fields." data-message-unknown-error="Sorry, an unknown error has occurred. Please try again later." class="emailoctopus-form" data-sitekey="6LdYsmsUAAAAAPXVTt-ovRsPIJ_IVhvYBBhGvRV6">
    <div class="emailoctopus-form-row">
      <label for="field_0">
        Email address
      </label>
      <input id="field_0" name="field_0" type="email" placeholder required="required">
    </div>
    <div aria-hidden="true" class="emailoctopus-form-row-hp">
      <input type="text" name="hpc4b27b6e-eb38-11e9-be00-06b4694bee2a" tabindex="-1" autocomplete="nope">
    </div>
    <div class="emailoctopus-form-row-subscribe">
      <input type="hidden" name="successRedirectUrl">
      <button type="submit" style="color: rgb(51, 51, 51); font-family: inherit; background-color: rgb(255, 87, 47);">
        Subscribe
      </button>
    </div>
  </form>
  <div class="emailoctopus-rewards" style="color: var(--darker-gray-color);">
    Powered by
    <a href="https://emailoctopus.com/?urli=5mTcC&amp;utm_medium=user_referral&amp;utm_source=builder" target="_blank">
      EmailOctopus
    </a>
  </div>
</div>
    
<script src="https://emailoctopus.com/bundles/emailoctopuslist/js/1.6/form-recaptcha.js">
</script>
<script src="https://emailoctopus.com/bundles/emailoctopuslist/js/1.6/form-embed.js">
</script>

<!--kg-card-end: html-->]]></content:encoded></item></channel></rss>