<?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: Ankur Bhardwaj</title>
    <description>The latest articles on DEV Community by Ankur Bhardwaj (@ankurbhardwaj).</description>
    <link>https://dev.to/ankurbhardwaj</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4196099%2F18e23063-74cf-4622-8371-77946f23fb6f.png</url>
      <title>DEV Community: Ankur Bhardwaj</title>
      <link>https://dev.to/ankurbhardwaj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ankurbhardwaj"/>
    <language>en</language>
    <item>
      <title>Which Letter Case Goes Where? A Practical Cheat Sheet</title>
      <dc:creator>Ankur Bhardwaj</dc:creator>
      <pubDate>Tue, 20 Oct 2026 13:34:28 +0000</pubDate>
      <link>https://dev.to/ankurbhardwaj/which-letter-case-goes-where-a-practical-cheat-sheet-2194</link>
      <guid>https://dev.to/ankurbhardwaj/which-letter-case-goes-where-a-practical-cheat-sheet-2194</guid>
      <description>&lt;p&gt;Capitalization looks like a detail until it's inconsistent. One heading in Title Case, the next in sentence case, a button in ALL CAPS, and a page starts to feel careless, even if nobody can say exactly why. Most of the time, the problem isn't knowing how to capitalize. It's knowing which case belongs where.&lt;/p&gt;

&lt;p&gt;This is the cheat sheet I wish I'd had: what each common case is, where it's normally used, and the traps that catch people when they convert text in bulk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cases, in one line each
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sentence case: only the first word and proper nouns are capitalized. "How to plan a garden in spring"&lt;/li&gt;
&lt;li&gt;Title Case: major words are capitalized, while short articles, conjunctions and (depending on style) prepositions stay lowercase. "How to Plan a Garden in Spring"&lt;/li&gt;
&lt;li&gt;Capitalized Case: every word starts with a capital. "How To Plan A Garden In Spring"&lt;/li&gt;
&lt;li&gt;UPPER CASE: every letter is a capital. "HOW TO PLAN A GARDEN IN SPRING"&lt;/li&gt;
&lt;li&gt;lower case: no capitals at all. "how to plan a garden in spring"&lt;/li&gt;
&lt;li&gt;aLtErNaTiNg and InVeRsE: playful cases for memes and fixing accidental Caps Lock.&lt;/li&gt;
&lt;li&gt;Programming cases: camelCase, PascalCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case, dot.case, plus URL slugs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most common mistake is treating Title Case and Capitalized Case as the same thing. They aren't, and editors notice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headlines and titles: Title Case, but pick a style
&lt;/h2&gt;

&lt;p&gt;For article headlines, book and chapter titles, and formal page titles, Title Case is the usual choice in English. The trouble is that there isn't one Title Case. The major style guides agree on the basics. Capitalize the first and last word, capitalize nouns, verbs, adjectives and adverbs, and keep "a", "an", "the", "and", "or" and "but" lowercase in the middle. They disagree about prepositions.&lt;/p&gt;

&lt;p&gt;Take the headline "walking through the park with the team after the storm":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AP and APA: Walking Through the Park With the Team After the Storm&lt;/li&gt;
&lt;li&gt;Chicago and MLA: Walking through the Park with the Team after the Storm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AP and APA capitalize prepositions of four or more letters. Chicago and MLA keep prepositions lowercase however long they are. Neither is wrong. What matters is following whichever guide your publication, school or client uses, and sticking to it. I put together a fuller side-by-side, including how hyphenated words differ, in &lt;a href="https://simplecaseconverter.com/ap-vs-apa-vs-chicago-vs-mla-title-case/" rel="noopener noreferrer"&gt;AP vs APA vs Chicago vs MLA title case&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A quick rule if no style is specified: news and web content usually follow AP, while books and general publishing usually follow Chicago.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interfaces and documentation: sentence case
&lt;/h2&gt;

&lt;p&gt;Most modern design systems use sentence case for buttons, menus, settings, form labels and headings in help docs. "Save changes", not "Save Changes". "Notification settings", not "Notification Settings". It reads like ordinary speech, it's easier to scan, and it removes the endless debate about whether "to" or "with" deserves a capital.&lt;/p&gt;

&lt;p&gt;Whatever you choose, be consistent across one product. Mixing the two styles in a single menu is the most visible mistake.&lt;/p&gt;

&lt;h2&gt;
  
  
  Academic references: check the list separately
&lt;/h2&gt;

&lt;p&gt;Academic styles often use different cases in different places. In APA, for example, your paper's own title and headings use title case, while article titles in the reference list use sentence case. So "Effects of Sleep on Memory" in the text becomes "Effects of sleep on memory" in the reference entry.&lt;/p&gt;

&lt;p&gt;When you clean up capitalization in a paper, convert the reference list on its own pass. Don't run the whole document through one conversion and assume it's right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Names and labels: Capitalized Case
&lt;/h2&gt;

&lt;p&gt;Capitalized Case, where every word starts with a capital, works for personal names, place names, product names and short labels such as table column headings. It's the wrong choice for headlines, because it capitalizes words like "Of" and "The" that every major style keeps lowercase.&lt;/p&gt;

&lt;p&gt;This is also exactly what spreadsheet and word-processor shortcuts produce. Excel's PROPER function and Word's "Capitalize Each Word" both give you "The Lord Of The Rings", not the correctly styled "The Lord of the Rings".&lt;/p&gt;

&lt;h2&gt;
  
  
  ALL CAPS: use sparingly
&lt;/h2&gt;

&lt;p&gt;Capitals are fine for short labels, acronyms and the occasional emphasis. Whole sentences or paragraphs in capitals are harder to read, because word shapes disappear, and they come across as shouting in email and chat. If you've received a document typed in Caps Lock, converting it to sentence case is usually the fastest fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code: follow the language's convention
&lt;/h2&gt;

&lt;p&gt;In code, case isn't style. It's convention, and sometimes it's enforced by linters. The common patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;camelCase: variables and functions in JavaScript, Java and similar languages. userName, getTotal&lt;/li&gt;
&lt;li&gt;PascalCase: classes, types and React components. UserProfile, OrderService&lt;/li&gt;
&lt;li&gt;snake_case: variables and functions in Python (PEP 8), and many database column names. user_name, created_at&lt;/li&gt;
&lt;li&gt;SCREAMING_SNAKE_CASE: constants and environment variables. MAX_RETRIES, API_BASE_URL&lt;/li&gt;
&lt;li&gt;kebab-case: CSS class names, file names and URL paths. main-header, user-settings&lt;/li&gt;
&lt;li&gt;dot.case: some config keys and namespaced identifiers. app.server.port&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Converting between these by hand is error-prone, especially with acronyms (is it "userId" or "userID"?). That's a good job for a converter, followed by a quick review.&lt;/p&gt;

&lt;h2&gt;
  
  
  URLs: lowercase slugs with hyphens
&lt;/h2&gt;

&lt;p&gt;For web addresses, the usual convention is lowercase words separated by hyphens, without punctuation or accents: /how-to-plan-a-garden. Hyphens are generally treated as word separators, mixed case can lead to duplicate URLs on some servers, and lowercase is simply easier to type and share. A &lt;a href="https://simplecaseconverter.com/slugify/" rel="noopener noreferrer"&gt;slug generator&lt;/a&gt; turns a title into this format in one step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traps when converting in bulk
&lt;/h2&gt;

&lt;p&gt;Automatic conversion is fast, but watch for these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acronyms and brands. A naive converter turns NASA into "Nasa" and iPhone into "Iphone". Check the result, or use a tool that keeps known proper nouns.&lt;/li&gt;
&lt;li&gt;The pronoun "I". Lowercasing everything and then capitalizing sentence starts can leave a stray "i" in the middle of a sentence.&lt;/li&gt;
&lt;li&gt;Proper nouns in sentence case. No tool knows every name. Expect to fix some people, places and products by hand.&lt;/li&gt;
&lt;li&gt;Turkish and other languages. In Turkish, "i" uppercases to "İ" and "ı" to "I". Using English rules on Turkish text produces wrong letters, so use a converter that lets you choose the locale.&lt;/li&gt;
&lt;li&gt;IDs, emails and codes. Bulk Capitalized Case will happily change SKU-ab12 or an email address. Keep those out of the selection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A tool for the job
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://simplecaseconverter.com" rel="noopener noreferrer"&gt;Simple Case Converter&lt;/a&gt; because I kept running into these exact problems. You can choose the title style (AP, APA, Chicago or MLA), it restores the pronoun "I" in sentence case, it has a smart proper-noun option and a locale setting for English, Turkish and German, and it covers the programming cases and slugs. The text is processed in your browser, so nothing you paste is uploaded. Whatever tool you use, the steps are the same: pick the case for the context, convert, then read the result once before you publish.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ankur Bhardwaj&lt;/em&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why Text Symbols Sometimes Show Up as Boxes (and How to Pick Ones That Don't)</title>
      <dc:creator>Ankur Bhardwaj</dc:creator>
      <pubDate>Tue, 20 Oct 2026 13:28:27 +0000</pubDate>
      <link>https://dev.to/ankurbhardwaj/why-text-symbols-sometimes-show-up-as-boxes-and-how-to-pick-ones-that-dont-50ii</link>
      <guid>https://dev.to/ankurbhardwaj/why-text-symbols-sometimes-show-up-as-boxes-and-how-to-pick-ones-that-dont-50ii</guid>
      <description>&lt;p&gt;You paste a neat little ✿ into your Instagram bio, and on your friend's phone it shows up as an empty box. Or your "𝓯𝓪𝓷𝓬𝔂" Discord nickname quietly reverts to plain letters. Text symbols are supposed to be simple, so why do they break?&lt;/p&gt;

&lt;p&gt;Text symbols are real Unicode characters, not images. That's what makes them so useful. It also means whether they show up depends on fonts, platforms and filters you don't control. Once you know the four ways they fail, it's easy to pick symbols that work for nearly everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why symbols work at all
&lt;/h2&gt;

&lt;p&gt;Every character you type, whether A, ♥ or →, is a code point in the Unicode standard. ♥ is U+2665, "Black Heart Suit". ★ is U+2605, "Black Star". When you paste one into a bio, a chat or a document, you're pasting text, just like a letter. That's why it stays selectable and searchable, and why it scales with the font size.&lt;/p&gt;

&lt;p&gt;The catch is that a character in the text is one thing, and a font that can draw it is another. The text carries the code point. The viewer's device has to supply the drawing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure 1: the empty box ("tofu")
&lt;/h2&gt;

&lt;p&gt;That empty rectangle, □, often nicknamed "tofu", means the character is there but the current font has no drawing for it. Nothing is corrupted. Copy that box and paste it somewhere with better font support, and the symbol often reappears.&lt;/p&gt;

&lt;p&gt;Tofu is most common with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rare ornaments and dingbats from little-used Unicode blocks.&lt;/li&gt;
&lt;li&gt;Kaomoji that borrow Japanese, Thai or Kannada characters. One missing glyph breaks the whole face.&lt;/li&gt;
&lt;li&gt;Newer emoji on phones that haven't been updated in a while.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix is to choose more widely supported characters. Classic ones like ♥ ★ ✓ → ✿ ☾ have been in Unicode for decades and display almost everywhere. There's a longer fix-it checklist in the &lt;a href="https://freetextsymbols.com/guides/symbol-not-showing/" rel="noopener noreferrer"&gt;symbol not showing guide&lt;/a&gt;, including which fonts to switch to in Google Docs or Photoshop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure 2: the heart changes color
&lt;/h2&gt;

&lt;p&gt;Some characters have two looks: a flat text style and a colored emoji style. The red ❤️ you see in most chat apps is the same base character as the black ❤ (U+2764). It's followed by an invisible "variation selector" (U+FE0F) that asks for the emoji presentation.&lt;/p&gt;

&lt;p&gt;That causes two kinds of surprises:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An app or font may ignore the selector and show the flat version, or force the emoji version when you wanted the flat one.&lt;/li&gt;
&lt;li&gt;Emoji artwork differs by platform. Your heart, face or sparkle can look quite different on an iPhone, an Android phone and Windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want a consistent look, use characters that only exist in text style. ♥ (U+2665) always stays a flat, font-colored heart. Save the colored emoji for places where a bit of variation doesn't matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure 3: "fancy fonts" that aren't fonts
&lt;/h2&gt;

&lt;p&gt;Bold, script and gothic letters like 𝐁𝐨𝐥𝐝, 𝓢𝓬𝓻𝓲𝓹𝓽 and 𝔊𝔬𝔱𝔥𝔦𝔠 aren't a font at all. They're separate characters, mostly from Unicode's "Mathematical Alphanumeric Symbols" block, which was meant for equations. A fancy-text generator swaps each normal letter for its lookalike.&lt;/p&gt;

&lt;p&gt;That trick works in many places, but it has real costs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search. Your name in script letters doesn't match a search for your name, because the characters are different. On a profile you want people to find, that matters.&lt;/li&gt;
&lt;li&gt;Screen readers. Many assistive tools read these characters by their long Unicode names or skip them, so a stylized name can be unreadable for blind and low-vision visitors.&lt;/li&gt;
&lt;li&gt;Platform filters. Some username and nickname fields normalize or reject them. That's why a Discord nickname or an app username field may silently revert to plain letters.&lt;/li&gt;
&lt;li&gt;Font gaps. Coverage for this block is patchy, especially on older Android devices, which brings back the tofu problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good compromise is to keep your name in normal letters and decorate around it: ✦ your name ✦, or ꧁ your name ꧂. If you do want a stylized word, use it for one short word, not your whole bio. The &lt;a href="https://freetextsymbols.com/fancy-text/" rel="noopener noreferrer"&gt;fancy text generator&lt;/a&gt; shows several styles side by side, so you can check which ones display on your own phone before you commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure 4: the platform strips it
&lt;/h2&gt;

&lt;p&gt;Even when a symbol displays fine, a particular field may not accept it. Bios, display names, usernames and captions often follow different rules within the same app. A rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Messages and captions are the most permissive.&lt;/li&gt;
&lt;li&gt;Bios are usually fine with dingbats and emoji, but long decorative strings may be trimmed by character limits. Some symbols also count as two characters.&lt;/li&gt;
&lt;li&gt;Usernames and handles are the strictest. Expect letters, numbers and a few punctuation marks only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A short checklist for bios and names that work everywhere
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lead with readable text and use symbols as decoration, not as replacement letters.&lt;/li&gt;
&lt;li&gt;Prefer long-established symbols (♥ ★ ✦ ✿ → ✓ ☾ ✉) over rare ornaments.&lt;/li&gt;
&lt;li&gt;Use a flat ♥ instead of a colored ❤️ when the look needs to be consistent.&lt;/li&gt;
&lt;li&gt;Keep stylized letters to one word, if you use them at all.&lt;/li&gt;
&lt;li&gt;Count characters. Bios have tight limits, and some symbols use up two "characters" of space.&lt;/li&gt;
&lt;li&gt;Test on another device before you rely on it, ideally both an iPhone and an Android phone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want a starting point, the &lt;a href="https://freetextsymbols.com/instagram-bio-symbols/" rel="noopener noreferrer"&gt;Instagram bio symbols page&lt;/a&gt; has ready-made lines like "✧ collabs welcome ✧" and "↓ link in bio ↓" that you can copy with one tap and edit.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you actually need an image
&lt;/h2&gt;

&lt;p&gt;Sometimes the text approach is the wrong tool. In slides, thumbnails, stickers and design files, you can't control which fonts the viewer has, and you don't need the symbol to stay selectable. In those cases an image is more reliable than text.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://freetextsymbols.com" rel="noopener noreferrer"&gt;Free Text Symbols&lt;/a&gt; to cover both cases. You can search the library by name, keyword or code point (U+2665 works) and click a symbol to copy it as text. Each symbol card also shows its Unicode name, HTML entity and CSS escape, and can export a PNG from 64 to 1024 px. Use text for bios and chats, and the image for design work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;Text symbols break in predictable ways: missing fonts (tofu), emoji vs text presentation, math letters pretending to be fonts, and fields that strip characters. Choose established symbols, keep real words readable, and test on a second device. Your ✿ will then show up the way you meant it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ankur Bhardwaj&lt;/em&gt;&lt;/p&gt;

</description>
      <category>unicode</category>
      <category>a11y</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Before You Print: A Checklist for Turning an OBJ Into a Good STL</title>
      <dc:creator>Ankur Bhardwaj</dc:creator>
      <pubDate>Tue, 20 Oct 2026 13:27:43 +0000</pubDate>
      <link>https://dev.to/ankurbhardwaj/before-you-print-a-checklist-for-turning-an-obj-into-a-good-stl-5d91</link>
      <guid>https://dev.to/ankurbhardwaj/before-you-print-a-checklist-for-turning-an-obj-into-a-good-stl-5d91</guid>
      <description>&lt;p&gt;You found the perfect model. It's an OBJ, your slicer wants an STL, and you're one conversion away from printing. In my experience that last step is where most of the trouble starts. The conversion itself is quick. What goes wrong is everything the OBJ was quietly carrying, or quietly missing.&lt;/p&gt;

&lt;p&gt;This is the checklist I run before any OBJ goes near a print bed. Most of it happens in Blender, or whichever app made the file, before you convert anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Make sure it's actually a mesh
&lt;/h2&gt;

&lt;p&gt;An STL can only hold triangles. If the OBJ came out of an app with curves, text objects or unapplied modifiers, parts of the model may not be real faces yet. They look fine in the viewport and then vanish from the export.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Blender, select the object and use Object → Convert → Mesh for curves and text.&lt;/li&gt;
&lt;li&gt;Apply any modifiers you want baked in (Mirror, Solidify, Boolean, Subdivision) before export.&lt;/li&gt;
&lt;li&gt;If the OBJ has no faces at all, only points or lines, there's nothing to print. A good converter will stop and tell you rather than hand you an empty file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Apply your transforms
&lt;/h2&gt;

&lt;p&gt;This is the most common invisible problem. An object can be scaled 0.01 in Blender's object properties while its actual vertex data is 100 times larger. Depending on the exporter settings, the file you get may not match what you see on screen.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the object and press Ctrl+A → Scale (and Rotation, if you rotated it).&lt;/li&gt;
&lt;li&gt;Check that the scale fields read 1, 1, 1 before you export.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do this first. Guessing a percentage in the slicer afterwards is how people end up stacking two scale fixes on top of each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Decide what one unit means
&lt;/h2&gt;

&lt;p&gt;STL files don't store units. A coordinate of 10 is just the number 10. Slicers such as Bambu Studio, UltiMaker Cura and PrusaSlicer almost always read it as 10 millimeters. Modeling apps often don't think in millimeters at all. Blender scenes commonly default to meters.&lt;/p&gt;

&lt;p&gt;The fix is to know your unit, not guess it. Pick a dimension you know: a miniature base that should be 25 mm, a phone stand that should be 80 mm wide, a hole that should fit a 5 mm bolt. Then compare it with the model's measured size.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About right: the file is in millimeters. Leave it alone.&lt;/li&gt;
&lt;li&gt;About 1000× too small: the file was in meters. Multiply by 1000.&lt;/li&gt;
&lt;li&gt;About 10× too small: centimeters. Multiply by 10.&lt;/li&gt;
&lt;li&gt;About 25× too small: inches. Multiply by 25.4.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wrote a longer explanation of this, with a worked example, in the &lt;a href="https://objtostl.com/units-mm-vs-meters" rel="noopener noreferrer"&gt;millimeters vs meters guide&lt;/a&gt;. The short version: apply the scale when you convert, so the STL's numbers are already in millimeters. Don't rely on remembering to fix it in the slicer.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Point it the right way up
&lt;/h2&gt;

&lt;p&gt;Many modeling tools and OBJ exporters treat Y as up. 3D printers and slicers treat Z as up. If you skip this, your figurine arrives lying on its back.&lt;/p&gt;

&lt;p&gt;While you're at it, put the model on the bed. If its lowest point sits at Z = 5 or Z = −30, some slicers will drop it automatically and others will warn you. Moving the mesh so its lowest Z is 0 removes the question.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Check that the mesh is watertight
&lt;/h2&gt;

&lt;p&gt;Converting a file copies triangles. It does not fix them. A slicer needs a closed, consistent surface, called manifold, to know what's inside and what's outside. Common faults:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Holes: missing faces, often at the bottom of scanned or game-ripped models.&lt;/li&gt;
&lt;li&gt;Flipped normals: faces pointing inward. Blender's Mesh → Normals → Recalculate Outside (Shift+N) fixes most of them.&lt;/li&gt;
&lt;li&gt;Non-manifold edges: an edge shared by three or more faces, or two shells touching at a single edge.&lt;/li&gt;
&lt;li&gt;Zero-thickness parts: a single plane for a cape, a leaf or a sign. It renders fine but has no volume to print.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Blender ships with a 3D Print Toolbox add-on (enable it in Preferences → Add-ons). Its Check All button flags non-manifold geometry, intersecting faces and thin walls in one pass. Use Select → Select All by Trait → Non Manifold for a quick look without the add-on.&lt;/p&gt;

&lt;p&gt;Fix these in the modeling app, then export again. A slicer's automatic repair can work, but it's guessing, and you won't always like what it guesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Think about wall thickness and detail size
&lt;/h2&gt;

&lt;p&gt;Your nozzle sets a floor. With a typical 0.4 mm nozzle, walls thinner than about 0.8 mm (two line widths) tend to print weakly, come out patchy or disappear. Detail smaller than the nozzle, like fine engraved text, thin hair strands or tiny spikes, will simply be lost.&lt;/p&gt;

&lt;p&gt;Models made for games or rendering are often not designed with this in mind. Thicken thin parts with a Solidify modifier, or scale the whole model up if fine detail matters more than size.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Keep the triangle count sensible
&lt;/h2&gt;

&lt;p&gt;Sculpts and 3D scans can have millions of triangles. That's far more than a printer can reproduce, and enough to make converters and slicers slow or unstable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blender's Decimate modifier (Collapse mode, ratio 0.3 to 0.5) usually cuts the count dramatically with no visible loss at print scale.&lt;/li&gt;
&lt;li&gt;Export only the object you plan to print, not the whole scene.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Know what the STL won't keep
&lt;/h2&gt;

&lt;p&gt;An STL is a plain triangle shell. Materials, the MTL file, texture images, UVs, vertex colors and object names don't come along. If the OBJ contains several objects, such as a figurine and a separate base, they usually end up merged into one triangle list.&lt;/p&gt;

&lt;p&gt;That's fine for a single-color print. If you want to print the parts separately, export them as separate OBJs. And always keep the original OBJ (plus its MTL) in your project folder, because the STL can't give that information back. The &lt;a href="https://objtostl.com/obj-vs-stl" rel="noopener noreferrer"&gt;OBJ vs STL comparison&lt;/a&gt; covers exactly what survives the conversion.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Convert, then read the numbers before you print
&lt;/h2&gt;

&lt;p&gt;When the checklist is done, convert. I built &lt;a href="https://objtostl.com" rel="noopener noreferrer"&gt;objtostl.com&lt;/a&gt; for this step. It runs in the browser, so the file stays on your machine. You choose the source unit (mm, cm, m or inches) and the up axis, and you can drop the mesh onto the bed. Before you download, it shows the bounding box in millimeters and the triangle count. Whichever converter you use, look for those two numbers.&lt;/p&gt;

&lt;p&gt;Then do one last check in the slicer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the size on the bed match the dimension you know from step 3?&lt;/li&gt;
&lt;li&gt;Is it the right way up and sitting flat?&lt;/li&gt;
&lt;li&gt;Did the slicer report any mesh errors when importing?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick reference: symptom → likely cause
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Model is invisible or a tiny speck → saved in meters, read as millimeters (step 3).&lt;/li&gt;
&lt;li&gt;Model is huge and fills the whole bed → coordinates already scaled up, or a scale applied twice (steps 2 and 3).&lt;/li&gt;
&lt;li&gt;Model lies on its side or back → Y-up vs Z-up (step 4).&lt;/li&gt;
&lt;li&gt;"Non-manifold" or "open edges" warning → holes or flipped faces (step 5).&lt;/li&gt;
&lt;li&gt;Parts missing in the sliced preview → walls thinner than the nozzle, or zero-thickness geometry (steps 5 and 6).&lt;/li&gt;
&lt;li&gt;Converter or slicer freezes → triangle count too high (step 7).&lt;/li&gt;
&lt;li&gt;Color or texture gone → expected, since STL has no materials (step 8).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Five minutes of checking beats a three-hour print the size of a grain of rice. If you hit a case this list doesn't cover, I'd like to hear about it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ankur Bhardwaj&lt;/em&gt;&lt;/p&gt;

</description>
      <category>3dprinting</category>
      <category>blender</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How OBJ to STL conversion works in the browser (no server needed)</title>
      <dc:creator>Ankur Bhardwaj</dc:creator>
      <pubDate>Tue, 20 Oct 2026 12:10:21 +0000</pubDate>
      <link>https://dev.to/ankurbhardwaj/how-obj-to-stl-conversion-works-in-the-browser-no-server-needed-1ip4</link>
      <guid>https://dev.to/ankurbhardwaj/how-obj-to-stl-conversion-works-in-the-browser-no-server-needed-1ip4</guid>
      <description>&lt;p&gt;I built &lt;a href="https://objtostl.com" rel="noopener noreferrer"&gt;objtostl.com&lt;/a&gt;, a free converter that turns a Wavefront OBJ file into an STL for 3D printing. The whole conversion happens in the browser tab. Here's how that works, and the things that go wrong if you skip them.&lt;/p&gt;

&lt;h3&gt;
  
  
  The two formats
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;OBJ&lt;/strong&gt; is a text format. The lines that matter for printing look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v 0.0 0.0 0.0      # vertex position
v 1.0 0.0 0.0
v 1.0 1.0 0.0
f 1 2 3            # face, 1-based vertex indices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Faces can have more than three vertices, indices can be negative (relative to the end of the list so far), and a face entry can carry texture and normal indices (&lt;code&gt;f 1/1/1 2/2/2 3/3/3&lt;/code&gt;). OBJ files often reference an &lt;code&gt;.mtl&lt;/code&gt; material file too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STL&lt;/strong&gt; is much simpler: a flat list of triangles. Binary STL is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an 80-byte header&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;uint32&lt;/code&gt; triangle count&lt;/li&gt;
&lt;li&gt;50 bytes per triangle: a normal (3 × float32), three vertices (9 × float32) and a 2-byte attribute field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;STL has no materials, no textures, no UVs, and &lt;strong&gt;no units&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File → parse OBJ → triangulate → scale to mm → fix axis → write binary STL → Blob → download
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read locally.&lt;/strong&gt; The browser File API gives you the bytes. No &lt;code&gt;fetch&lt;/code&gt;, no &lt;code&gt;POST&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parse in a Web Worker.&lt;/strong&gt; A 40 MB OBJ can freeze the main thread if you parse it there. Handing the work to a worker keeps the UI responsive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Triangulate.&lt;/strong&gt; Any face with more than 3 vertices has to be split into triangles. A simple fan (v0, vi, vi+1) works for convex faces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolve indices.&lt;/strong&gt; Convert 1-based and negative indices to absolute ones, and ignore the &lt;code&gt;vt&lt;/code&gt; and &lt;code&gt;vn&lt;/code&gt; parts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the binary STL&lt;/strong&gt; into an &lt;code&gt;ArrayBuffer&lt;/code&gt; with a &lt;code&gt;DataView&lt;/code&gt;, little-endian, then wrap it in a &lt;code&gt;Blob&lt;/code&gt; and trigger a download.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Units: the 1000× bug
&lt;/h3&gt;

&lt;p&gt;Because STL is unitless, slicers such as Bambu Studio, Cura and PrusaSlicer usually read 1 unit as 1 mm. If the OBJ was authored in meters, your 2 m-tall statue becomes a 2 mm speck. So the converter asks for the &lt;strong&gt;source unit&lt;/strong&gt; (mm, cm, m or inches) and multiplies every coordinate before writing. It also shows the &lt;strong&gt;bounding box in millimeters&lt;/strong&gt; and the &lt;strong&gt;triangle count&lt;/strong&gt;, which lets you sanity-check the size before you slice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Axis: Y-up vs Z-up
&lt;/h3&gt;

&lt;p&gt;Blender and many OBJ exporters use Y-up. Printers use Z-up. Rotating Y-up to Z-up swaps the axes, and an optional "sit on bed" step translates the mesh so its lowest Z is 0.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I deliberately don't do
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Materials and textures are dropped.&lt;/strong&gt; STL can't hold them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There's no mesh repair.&lt;/strong&gt; If your slicer reports a non-manifold mesh, fix it in Blender. Silently "repairing" geometry can hide real problems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Binary is the default.&lt;/strong&gt; It's far smaller than ASCII STL, though ASCII is still available as an option.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verifying "no upload"
&lt;/h3&gt;

&lt;p&gt;Open DevTools → Network and drop a file. You shouldn't see any request whose body is your mesh. The only mesh the site ever serves is its own sample cube. Anyone can check that claim in about ten seconds.&lt;/p&gt;

&lt;p&gt;The tool also converts STL back to OBJ, and has guides for FBX → OBJ → STL via Blender.&lt;/p&gt;

&lt;p&gt;I run two other small browser-only tools in the same spirit: &lt;a href="https://freetextsymbols.com" rel="noopener noreferrer"&gt;Free Text Symbols&lt;/a&gt;, a Unicode symbol picker, and &lt;a href="https://simplecaseconverter.com" rel="noopener noreferrer"&gt;Simple Case Converter&lt;/a&gt;. Feedback on the converter's edge cases (odd OBJ exporters, huge files) is very welcome.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>3dprinting</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
