<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Lopez</title>
    <description>The latest articles on DEV Community by David Lopez (@letsbelopez).</description>
    <link>https://dev.to/letsbelopez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F354482%2F6e5adad4-c978-4a28-bb85-7b12f11f3cc0.jpg</url>
      <title>DEV Community: David Lopez</title>
      <link>https://dev.to/letsbelopez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/letsbelopez"/>
    <language>en</language>
    <item>
      <title>Lessons Learned Building a React Auth Library with Cursor.</title>
      <dc:creator>David Lopez</dc:creator>
      <pubDate>Tue, 18 Mar 2025 16:07:57 +0000</pubDate>
      <link>https://dev.to/letsbelopez/lessons-learned-building-a-react-auth-library-with-cursor-2ko3</link>
      <guid>https://dev.to/letsbelopez/lessons-learned-building-a-react-auth-library-with-cursor-2ko3</guid>
      <description>&lt;h2&gt;
  
  
  What Surprised Me About AI's Help?
&lt;/h2&gt;

&lt;p&gt;Using &lt;strong&gt;Cursor IDE&lt;/strong&gt; with &lt;strong&gt;Claude 3.5 Sonnet&lt;/strong&gt;, I found coding became much easier, even for someone like me who already knows how to program. As a dad with one kid and two more on the way, I don’t have a lot of free time for side projects. But with &lt;strong&gt;Cursor's composer feature in "agent" mode&lt;/strong&gt;, I could type in a few prompts before work or while eating breakfast. Once I saw how fast it was to add new features and test them, I was motivated to continue and could spend an hour or two working on the project.&lt;/p&gt;

&lt;p&gt;One of the hardest things about side projects is staying motivated. Since I already code for my job, I don’t always feel like doing more of it in my free time. But &lt;strong&gt;Cursor's AI felt like a coding buddy&lt;/strong&gt; instead of just a tool. The &lt;strong&gt;agent composer mode&lt;/strong&gt;, which can use tools, run terminal commands, and edit files, kept track of things for me, so I didn’t have to remember every little detail.&lt;/p&gt;

&lt;p&gt;Another cool thing was how &lt;strong&gt;Claude 3.5 Sonnet in Cursor changed my workflow&lt;/strong&gt;. I didn’t have to write all the code myself. I could just check what it suggested, see if it looked good, and then move forward. I didn't get hung up coding and optimizing line by line—I just focused on getting things done. If there were mistakes, I knew I could debug them later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor IDE also helped me try out new tools.&lt;/strong&gt; For this project, I used &lt;code&gt;vite&lt;/code&gt;, &lt;code&gt;nx&lt;/code&gt;, and &lt;code&gt;pnpm&lt;/code&gt;—tools I hadn’t used much before. Normally, setting up new tools takes a lot of time because you have to figure out all the settings. But &lt;strong&gt;Claude 3.5 Sonnet helped me skip most of that by giving me quick answers instead of making me dig through documentation.&lt;/strong&gt; That saved me a ton of time and effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Did AI Slow Me Down?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cursor's AI wasn’t great at setting up my project in the beginning.&lt;/strong&gt; It defaulted to using an outdated project setup tool, Create React App, which no one uses anymore because it's no longer maintained.&lt;/p&gt;

&lt;p&gt;I wanted a specific project setup using &lt;code&gt;pnpm&lt;/code&gt;, &lt;code&gt;vite&lt;/code&gt;, and &lt;code&gt;nx&lt;/code&gt; to build a monorepo (a setup where multiple projects live in one big folder). It ended up being easier and faster to use the code generators in these tools instead of relying on Cursor's AI to generate the scaffolding. AI was helpful for giving me the right terminal commands for these tools, but I still had to know about them and &lt;strong&gt;tell it specifically to use them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another issue was that &lt;strong&gt;Cursor sometimes got confused about how my project was organized.&lt;/strong&gt; Since I was using a monorepo, AI sometimes acted like it was working on just one small project.&lt;/p&gt;

&lt;p&gt;When it tried to fix bugs, it would often get stuck in a rut, and it felt like it was trying to fix the bug by brute force. In these situations, &lt;strong&gt;reminding it that it was just working before the last change helped get it back on track&lt;/strong&gt;. Also, reminding it that it was working in a monorepo helped too.&lt;/p&gt;

&lt;p&gt;When I needed a way to refresh login tokens, &lt;strong&gt;Cursor's AI added an import statement for a function that didn’t exist in the library I was building&lt;/strong&gt;. It would have been nice if it also realized that it needed to implement this function for it to work. It was another sign that &lt;strong&gt;Claude 3.5 Sonnet lost the monorepo context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If I had blindly accepted all of Cursor's AI suggestions, my project would have ended up broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Would a Non-AI Approach Have Been Better?
&lt;/h2&gt;

&lt;p&gt;In some cases, yes. Using the official setup tools (&lt;code&gt;nx&lt;/code&gt;, &lt;code&gt;vite&lt;/code&gt;, etc.) was way better than trying to get AI to generate everything from scratch.&lt;/p&gt;

&lt;p&gt;One thing &lt;strong&gt;Claude 3.5 Sonnet in Cursor IDE&lt;/strong&gt; could do better is recognizing when existing tools are the best choice. Instead of trying to write all the setup code, &lt;strong&gt;AI should have just told me to use these tools&lt;/strong&gt; to generate code and build new packages from scratch. Even when I told AI to copy a popular open-source monorepo setup, it didn’t get it right. It didn’t use the right tools, and it didn’t even create a real monorepo.&lt;/p&gt;

&lt;p&gt;But once I got past the setup stage, &lt;strong&gt;Cursor’s AI-powered agent composer was really helpful&lt;/strong&gt; for writing the rest of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next for This Project?
&lt;/h2&gt;

&lt;p&gt;I’d love for other developers to try it out and tell me what features they need. Some ideas I have for improvements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A pre-made React component for signing in and signing up.&lt;/li&gt;
&lt;li&gt;Better options for customizing how users sign up.&lt;/li&gt;
&lt;li&gt;A way to recover lost passwords.&lt;/li&gt;
&lt;li&gt;Support for passwordless login and multi-factor authentication (MFA).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The big goal is to create a simple React library that connects to AWS Cognito without requiring a bunch of extra tools. This would let developers add authentication to their apps without needing to install unnecessary software.&lt;/p&gt;

&lt;p&gt;I plan to use this library in my own future projects because it makes setting up authentication so much easier.&lt;/p&gt;

&lt;p&gt;If you're interested in checking out the project or contributing, you can find the repository here: &lt;a href="https://github.com/letsbelopez/cognito" rel="noopener noreferrer"&gt;GitHub - letsbelopez/cognito&lt;/a&gt;. Feedback and suggestions are always welcome!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;AI is an amazing tool, but it’s not perfect.&lt;/strong&gt; It’s great for making coding easier, speeding up repetitive tasks, and writing boilerplate code, but it still needs human oversight. &lt;strong&gt;Cursor IDE with Claude 3.5 Sonnet didn’t replace my coding skills—it just helped me work faster.&lt;/strong&gt; And that’s what excites me the most about the future of AI-assisted development.&lt;/p&gt;

</description>
      <category>cursor</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to Load a PDF in a Browser from a PDF Byte Array</title>
      <dc:creator>David Lopez</dc:creator>
      <pubDate>Mon, 23 Mar 2020 17:26:22 +0000</pubDate>
      <link>https://dev.to/letsbelopez/how-to-load-a-pdf-in-a-browser-from-a-pdf-byte-array-56ic</link>
      <guid>https://dev.to/letsbelopez/how-to-load-a-pdf-in-a-browser-from-a-pdf-byte-array-56ic</guid>
      <description>&lt;p&gt;I got stuck on this seemingly easy task. I've somehow had gone my whole career without having to do this, but I've seen it done countless times on other sites.&lt;/p&gt;

&lt;p&gt;I think the reason why I got stuck was because I tried the most complex solutions first thinking that they're more likely to work. I was wrong. Lesson learned. Try the easiest solution first.&lt;/p&gt;

&lt;p&gt;Here's my solution. I ended up using an embed tag and make the src attribute equal to the api endpoint that was returning the byte array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pdf"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;embed&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://api_url/path/to/endpoint"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/pdf"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your last step would be to style it however you want and configure the PDF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the PDF
&lt;/h2&gt;

&lt;p&gt;After you get the PDF loading, you may also be wondering how to size the PDF to fit in the &lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;The problem is that your PDF may not always fit beautifully in the browser window when it loads. Maybe it's really small or it's too large. This article is how to fix that.&lt;/p&gt;

&lt;p&gt;There are specific types of query parameters for interacting with a PDF in the browser. You use these to help format the PDF. They look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;filename.pdf#view=FitH&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And in the case where we're using the &lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;embed&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://api_url/path/to/endpoint#view=FitH"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/pdf"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of the parameters starting with a '?', it will start with a '#'. The '#' and everything after is called a fragment. Fragments don't get sent to the server during an HTTP request.&lt;/p&gt;

&lt;p&gt;The keys and values in the fragment will tell the browser how to size the PDF. Follow the link below for a list of possible keys and values to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf" rel="noopener noreferrer"&gt;https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted the PDF page to fit on the page and using this fragment, &lt;code&gt;#view=FitV&lt;/code&gt;, solved my problem.&lt;/p&gt;

&lt;p&gt;You may think it's strange that your typing in these keys and values into Chrome but they come from an Adobe document. Me too. I think it's because Chrome tried to use Adobe's system but I couldn't find any information about it from Google. All keys and values may not be properly documented or map over into Chrome. You'll have to test them out for now. If you find any better documentation, please let me know.&lt;/p&gt;

&lt;p&gt;Now go ahead and try a few of these PDF query parameter fragments on your own PDF.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>html</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
