<?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: Sreehari S J</title>
    <description>The latest articles on DEV Community by Sreehari S J (@sreehari_sj_1d3d883c0f6b).</description>
    <link>https://dev.to/sreehari_sj_1d3d883c0f6b</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%2F3473443%2F59a55af6-f395-4af5-a697-7b75ab491f53.jpg</url>
      <title>DEV Community: Sreehari S J</title>
      <link>https://dev.to/sreehari_sj_1d3d883c0f6b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sreehari_sj_1d3d883c0f6b"/>
    <language>en</language>
    <item>
      <title>Building a Heart Risk Detector from Scratch with NumPy - Lessons in Overfitting &amp; Neural Networks</title>
      <dc:creator>Sreehari S J</dc:creator>
      <pubDate>Sat, 06 Sep 2025 15:59:41 +0000</pubDate>
      <link>https://dev.to/sreehari_sj_1d3d883c0f6b/building-a-heart-risk-detector-from-scratch-with-numpy-lessons-in-overfitting-neural-networks-5fki</link>
      <guid>https://dev.to/sreehari_sj_1d3d883c0f6b/building-a-heart-risk-detector-from-scratch-with-numpy-lessons-in-overfitting-neural-networks-5fki</guid>
      <description>&lt;p&gt;As part of my journey into neural networks, I recently built a &lt;strong&gt;Heart Risk Detector&lt;/strong&gt; from scratch using &lt;strong&gt;NumPy&lt;/strong&gt;, no TensorFlow, no PyTorch. The goal was to predict the risk of heart disease using structured clinical data. Here’s a version of my experience, the technical choices I made, and the challenges I tackled.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Project Overview
&lt;/h2&gt;

&lt;p&gt;The model is a &lt;strong&gt;binary classifier&lt;/strong&gt; trained on a dataset of numeric and categorical features. I implemented everything from scratch: data preprocessing, forward and backward passes, and training with regularization. Key highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data split:&lt;/strong&gt; 70% train, 15% validation, 15% test (randomized but reproducible).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preprocessing:&lt;/strong&gt; Min-max normalization of numeric features, one-hot encoding for categorical features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model architecture:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  Input → Dense(16, ReLU) → Dropout → Dense(8, ReLU) → Dropout → Dense(1, Sigmoid)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optimization:&lt;/strong&gt; Mini-batch SGD with learning rate 0.01.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regularization:&lt;/strong&gt; L2 weight decay + Dropout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Early stopping:&lt;/strong&gt; Tracks validation loss to prevent overfitting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overfitting Struggles
&lt;/h2&gt;

&lt;p&gt;At first, my model &lt;strong&gt;overfit&lt;/strong&gt; quickly—training accuracy shot up, but validation stagnated. I realized that my network was memorizing the training data rather than learning patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  The method by which I solved it
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dropout:&lt;/strong&gt; Applied 30% inverted dropout in hidden layers during training to prevent co-adaptation of neurons.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;L2 Regularization:&lt;/strong&gt; Penalized large weights, which helped reduce model complexity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Stopping:&lt;/strong&gt; Monitored validation loss and restored the best weights when no improvement was observed for 50 epochs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proper Data Preprocessing:&lt;/strong&gt; Normalizing numeric features using only training stats and aligning categorical features across splits prevented subtle data leakage.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;by doing this training and validation accuracies became much closer, and the model generalized better on unseen test data&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Insights From This
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Forward &amp;amp; Backward Pass:&lt;/strong&gt; Implemented ReLU and Sigmoid activations, and manually derived gradients for backpropagation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parameter Initialization:&lt;/strong&gt; Used He/Xavier scaling to stabilize gradients.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reproducibility:&lt;/strong&gt; Fixed random seeds for data splits and dropout masks, ensuring consistent results across runs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building a neural network from scratch is &lt;strong&gt;valuable for understanding the math and mechanics&lt;/strong&gt; behind high-level libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overfitting is inevitable with small datasets, but &lt;strong&gt;simple tools like dropout, L2, and early stopping&lt;/strong&gt; can save the day.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proper preprocessing and careful handling of categorical features can &lt;strong&gt;significantly affect model performance&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Experiment with &lt;strong&gt;Adam optimizer&lt;/strong&gt; and learning rate schedules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement &lt;strong&gt;Batch Normalization&lt;/strong&gt; to mitigate internal covariate shifts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explore &lt;strong&gt;imbalanced datasets&lt;/strong&gt; handling with class weighting or focal loss.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This project was not just a technical work taught me patience, debugging, and how subtle design choices impact model performance.&lt;/p&gt;

&lt;p&gt;If you’ve ever stucked with overfitting or any experience I’d love to hear your experience!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/posts/sreeharisj_i-built-a-neural-network-completely-from-activity-7369330335236517888-A5Mj?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAAFCbgXsB0HwI7lPlfELHDa9gDDuANItgIQ8" rel="noopener noreferrer"&gt;Check out my linkedin post about this&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sjsreehari/Heart-Risk-Detector-NeuralNetwork" rel="noopener noreferrer"&gt;Give me a star on github if you like it &lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building My First AI Project: Tic Tac Toe with Minimax (No ML Libraries)</title>
      <dc:creator>Sreehari S J</dc:creator>
      <pubDate>Wed, 03 Sep 2025 10:43:26 +0000</pubDate>
      <link>https://dev.to/sreehari_sj_1d3d883c0f6b/building-my-first-ai-project-tic-tac-toe-with-minimax-no-ml-libraries-2mbc</link>
      <guid>https://dev.to/sreehari_sj_1d3d883c0f6b/building-my-first-ai-project-tic-tac-toe-with-minimax-no-ml-libraries-2mbc</guid>
      <description>&lt;p&gt;I recently started exploring AI through &lt;strong&gt;Harvard CS50’s AI course&lt;/strong&gt;, and I decided to implement my &lt;strong&gt;first AI project&lt;/strong&gt; from scratch in Python: a &lt;strong&gt;Tic Tac Toe AI using the Minimax algorithm&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal wasn’t just to make a working game—but to &lt;strong&gt;understand AI concepts deeply by implementing them myself&lt;/strong&gt;. Here’s a breakdown of what I learned and applied.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned from CS50 AI
&lt;/h2&gt;

&lt;p&gt;The course covers a broad spectrum of AI topics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt; – How to find solutions to problems, like navigating from point A to B or making optimal moves in a game.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge &amp;amp; Inference&lt;/strong&gt; – Representing information and drawing conclusions from it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uncertainty&lt;/strong&gt; – Using probability to make decisions under uncertain conditions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimization&lt;/strong&gt; – Not just finding any solution, but the best solution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning&lt;/strong&gt; – Improving performance from experience, like distinguishing spam emails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neural Networks &amp;amp; Language Processing&lt;/strong&gt; – For more complex AI tasks beyond search and strategy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I focused on &lt;strong&gt;search and adversarial search&lt;/strong&gt;, which are foundational for game AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concepts Applied
&lt;/h2&gt;

&lt;p&gt;Before coding, I had to understand a few key AI concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt; – The “decision-maker” in the system (our AI player).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt; – A snapshot of the environment (board configuration).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actions&lt;/strong&gt; – Possible moves from a state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transition Model&lt;/strong&gt; – What happens when an action is applied.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Space&lt;/strong&gt; – All possible states reachable from the initial state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goal Test &amp;amp; Utility&lt;/strong&gt; – Checking if the game is over and assigning value (+1 win, -1 loss, 0 tie).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This framework helped me reason about the game in a &lt;strong&gt;structured, AI-centric way&lt;/strong&gt; rather than just coding moves randomly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Minimax?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqoea1meg59gxbdnmmbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqoea1meg59gxbdnmmbr.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tic Tac Toe is a &lt;strong&gt;small, adversarial game&lt;/strong&gt;, which makes it perfect to experiment with &lt;strong&gt;Minimax&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maximizer vs Minimizer&lt;/strong&gt; – The AI tries to maximize its score while assuming the opponent tries to minimize it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursion&lt;/strong&gt; – For each move, the algorithm simulates all possible future moves to decide the best one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depth-Limited Search&lt;/strong&gt; – Useful for bigger games (like Chess) to avoid exploring an intractable number of states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alpha-Beta Pruning&lt;/strong&gt; – Skips obviously bad moves to optimize computation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By implementing Minimax, I could see firsthand how the AI anticipates every possible opponent move—something that reading theory alone can’t fully convey.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementation Insights
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbid6ab1o0jt9fok33vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbid6ab1o0jt9fok33vg.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built functions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Actions(state)&lt;/code&gt; – Returns all valid moves.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Result(state, action)&lt;/code&gt; – Returns the board after a move.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Terminal(state)&lt;/code&gt; – Checks if the game is over.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Utility(state)&lt;/code&gt; – Evaluates the outcome of terminal states.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, using recursive &lt;strong&gt;Max-Value&lt;/strong&gt; and &lt;strong&gt;Min-Value&lt;/strong&gt; functions, the AI evaluates each move:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;max_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;terminal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;utility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;inf&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;min_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The minimizing player works similarly, ensuring optimal play from both sides. The result? An AI that &lt;strong&gt;never loses&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Minimax is ideal for &lt;strong&gt;small, perfect-information games&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Real-world games require &lt;strong&gt;heuristics&lt;/strong&gt; and &lt;strong&gt;pruning strategies&lt;/strong&gt; to handle enormous state spaces.&lt;/li&gt;
&lt;li&gt;Coding the algorithm reinforced my understanding of &lt;strong&gt;state spaces, goal tests, and recursive evaluation&lt;/strong&gt; far better than studying theory alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project gave me a &lt;strong&gt;solid foundation in adversarial search&lt;/strong&gt;, and I’m now excited to tackle larger games and explore heuristic-based AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Apply &lt;strong&gt;depth-limited Minimax&lt;/strong&gt; to Chess or Connect Four.&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;heuristics and evaluation functions&lt;/strong&gt; for faster decision-making.&lt;/li&gt;
&lt;li&gt;Experiment with &lt;strong&gt;reinforcement learning&lt;/strong&gt; for more complex AI.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Share your thoughts on my post here : &lt;a href="https://www.linkedin.com/posts/sreeharisj_ai-machinelearning-algorithms-activity-7368905636861927425-M0lD?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAAFCbgXsB0HwI7lPlfELHDa9gDDuANItgIQ8" rel="noopener noreferrer"&gt;Linkedin Post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the code here: &lt;a href="https://lnkd.in/dxhNDwKD" rel="noopener noreferrer"&gt;Tic Tac Toe Minimax Python&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt;&lt;br&gt;
#AI #Python #GameAI #Algorithms #Minimax #AdversarialSearch #CS50 #Programming #LearningByDoing&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Credit:&lt;/strong&gt;&lt;br&gt;
Images and course content referenced in this post are from &lt;strong&gt;&lt;a href="https://cs50.harvard.edu/ai/2020/" rel="noopener noreferrer"&gt;Harvard CS50’s Introduction to Artificial Intelligence with Python&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>algorithms</category>
      <category>python</category>
    </item>
    <item>
      <title>Encypher : Secure Your React State with Encrypted localStorage and sessionStorage</title>
      <dc:creator>Sreehari S J</dc:creator>
      <pubDate>Mon, 01 Sep 2025 15:42:16 +0000</pubDate>
      <link>https://dev.to/sreehari_sj_1d3d883c0f6b/encypher-secure-your-react-state-with-encrypted-localstorage-and-sessionstorage-5937</link>
      <guid>https://dev.to/sreehari_sj_1d3d883c0f6b/encypher-secure-your-react-state-with-encrypted-localstorage-and-sessionstorage-5937</guid>
      <description>&lt;p&gt;As developers, we often store user preferences, tokens, and other sensitive data in the browser. But how secure is your &lt;code&gt;localStorage&lt;/code&gt; or &lt;code&gt;sessionStorage&lt;/code&gt;? Enter &lt;strong&gt;Encypher&lt;/strong&gt; – a lightweight React hook that brings AES-GCM encryption to your front-end state management with an easy &lt;code&gt;useState&lt;/code&gt;-like API. Let’s dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  Why You Need Encrypted Storage in React
&lt;/h2&gt;

&lt;p&gt;React makes state management easy, but storing data directly in the browser can be risky:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokens and session info are vulnerable to XSS attacks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;localStorage&lt;/code&gt;/&lt;code&gt;sessionStorage&lt;/code&gt; is plaintext by default.&lt;/li&gt;
&lt;li&gt;Legacy fallback mechanisms often sacrifice security.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Encypher&lt;/strong&gt; solves this by encrypting data with AES-GCM and providing optional XOR fallback for legacy browsers. You can also set a &lt;strong&gt;time-to-live (TTL)&lt;/strong&gt; for auto-expiring storage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features of Encypher
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AES-GCM encryption using the Web Crypto API.&lt;/li&gt;
&lt;li&gt;Custom secret per hook or global via &lt;code&gt;EncryptedStorageProvider&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Optional TTL for expiring sensitive data.&lt;/li&gt;
&lt;li&gt;Works with &lt;code&gt;localStorage&lt;/code&gt;, &lt;code&gt;sessionStorage&lt;/code&gt;, or custom storage.&lt;/li&gt;
&lt;li&gt;Syncs across tabs/windows.&lt;/li&gt;
&lt;li&gt;XOR fallback for legacy browsers (not secure).&lt;/li&gt;
&lt;li&gt;Simple API: &lt;code&gt;[value, setValue, remove, reencrypt]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tested with React 17/18.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;encypher
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn add encypher
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then import the hook into your React component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEncryptedStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;encypher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv62buofeoqt7cv47qakn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv62buofeoqt7cv47qakn.png" alt="VS Code ScreenShot" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Usage Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEncryptedStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;encypher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removeUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useEncryptedStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-strong-secret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "session" is also supported&lt;/span&gt;
    &lt;span class="na"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 1 hour TTL&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Store&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;removeUser&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Remove&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Treat &lt;code&gt;useEncryptedStorage&lt;/code&gt; like &lt;code&gt;useState&lt;/code&gt;, but with encryption built-in.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Using a Global Secret with Provider
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EncryptedStorageProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEncryptedStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;encypher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EncryptedStorageProvider&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-global-secret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/EncryptedStorageProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Custom Storage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useEncryptedStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-secret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customStorage&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  API Overview
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useEncryptedStorage(key, initialValue, options)&lt;/code&gt; returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reencrypt&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;value&lt;/code&gt;: current decrypted value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setValue(val)&lt;/code&gt;: asynchronously encrypt and store&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove()&lt;/code&gt;: remove stored value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reencrypt(newSecret)&lt;/code&gt;: re-encrypt existing data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Options object includes:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// Required encryption key&lt;/span&gt;
  &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// "local", "session", or custom&lt;/span&gt;
  &lt;span class="nx"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Optional expiration time&lt;/span&gt;
  &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// "xor" for legacy fallback&lt;/span&gt;
  &lt;span class="nx"&gt;onFallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Callback if fallback is used&lt;/span&gt;
  &lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// Callback on error&lt;/span&gt;
  &lt;span class="nx"&gt;onReencrypt&lt;/span&gt;      &lt;span class="c1"&gt;// Callback after re-encryption&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Security Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always use a strong, unique secret.&lt;/li&gt;
&lt;li&gt;XOR fallback is insecure, only for non-sensitive data.&lt;/li&gt;
&lt;li&gt;AES-256 keys are derived via PBKDF2.&lt;/li&gt;
&lt;li&gt;Not suitable for highly sensitive or regulated data.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5q87fnklwuxudv6s8fy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5q87fnklwuxudv6s8fy.png" alt="Demo Webpage ScreenShot" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Encypher Demo Website
&lt;/h2&gt;

&lt;p&gt;Test all features live on the &lt;strong&gt;&lt;a href="https://encypher-demo-website.netlify.app/" rel="noopener noreferrer"&gt;Encypher Demo Website&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo Highlights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption &amp;amp; decryption with custom secrets&lt;/li&gt;
&lt;li&gt;TTL-based expiry testing&lt;/li&gt;
&lt;li&gt;Debug view of encrypted data&lt;/li&gt;
&lt;li&gt;Real-time interactive testing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Encypher is Developer-Friendly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easy to adopt:&lt;/strong&gt; &lt;code&gt;useState&lt;/code&gt;-like API means zero learning curve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible:&lt;/strong&gt; Use &lt;code&gt;localStorage&lt;/code&gt;, &lt;code&gt;sessionStorage&lt;/code&gt;, or custom storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure by default:&lt;/strong&gt; AES-GCM ensures modern encryption standards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reactive:&lt;/strong&gt; Works seamlessly with React state updates.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Secure your React state in style! Whether you’re storing user tokens, preferences, or other sensitive data, Encypher makes encryption effortless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Combine Encypher with your existing state management to add a security layer without changing your workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get started today:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NPM Package:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/encypher" rel="noopener noreferrer"&gt;encypher&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/sjsreehari/encypher" rel="noopener noreferrer"&gt;sjsreehari/encypher&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://encypher-demo-website.netlify.app/" rel="noopener noreferrer"&gt;encypher-demo-website.netlify.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Follow me for more tips and tools on React and front-end development! &lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>npm</category>
    </item>
  </channel>
</rss>
