<story><title>Best practices for TypeScript monorepo</title><url>https://blog.flycode.com/best-practices-for-typescript-monorepo</url></story><parent_chain><item><author>madeofpalk</author><text>&amp;gt; Use Absolute Paths for Importing Code Blocks&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { FormType } from &amp;#x27;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;types&amp;#x2F;form&amp;#x27;;
    import { DateType }   from &amp;#x27;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;types&amp;#x2F;date&amp;#x27;;
    
    &amp;#x2F;&amp;#x2F; This is considered bad practice
&lt;/code&gt;&lt;/pre&gt;
Disagree on this one. Beauty of typescript is giving you auto-import autocompletion in your editor, and not having to worry about relative paths any more. I don&amp;#x27;t think I&amp;#x27;ve manually written an import statement in years.</text></item></parent_chain><comment><author>015a</author><text>All code is fast to write. Decisions like this should be optimized for reading and comprehension, not writing.&lt;p&gt;IMO: Extreme opinions one way or the other don&amp;#x27;t work, and thus (most of the time) code-complete automation also doesn&amp;#x27;t work.&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { User } from &amp;quot;.&amp;#x2F;User&amp;quot;; # is probably the most readable and comprehensible way to write this.
    import { User } from &amp;quot;app&amp;#x2F;domain&amp;#x2F;users&amp;#x2F;types&amp;#x2F;User&amp;quot;; # is probably less comprehensible
    import { User } from &amp;quot;..&amp;#x2F;User&amp;quot;; # may be ok, but it may also depend on how deep this directory is, because
    import { User } from &amp;quot;app&amp;#x2F;users&amp;quot;; # is actually pretty comprehensible
&lt;/code&gt;&lt;/pre&gt;
The point should be to make it really quick for readers to understand where this code is coming from. Imagine a situation where you&amp;#x27;ve got identically named imports; like a&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { User } from &amp;quot;foo&amp;#x2F;db&amp;#x2F;types&amp;quot;; # used to schematize a user in the database
    import { User } from &amp;quot;foo&amp;#x2F;api&amp;#x2F;createUser&amp;#x2F;types&amp;quot;; # used to schematize a component of the request body for creating users
&lt;/code&gt;&lt;/pre&gt;
Maybe the tokens themselves are named poorly, but look past that.&lt;p&gt;Many people find a specific file using, simply, CMD+P (or your editor&amp;#x27;s equivalent). There&amp;#x27;s no context for where they may be at; which inherently makes relative imports less comprehensible.&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { User } from &amp;quot;.&amp;#x2F;User&amp;quot;;
    const u = new User(req.body.user); # but wait... what kind of user did I just create?
&lt;/code&gt;&lt;/pre&gt;
There are many ways to help alleviate this low state of comprehension; and what should be deployed is difficult to create hard-and-fast rules around because its so domain specific.&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { User } from &amp;quot;foo&amp;#x2F;api&amp;#x2F;createUser&amp;#x2F;types&amp;quot;; 
    # having an import path like this can help, but maybe only in small files where the imports aren&amp;#x27;t 500 lines above where they&amp;#x27;re used.

    import { User as CreateUserAPIUser } from &amp;quot;.&amp;#x2F;User&amp;quot;; 
    # aliasing imports is a good solution 
    
    import * as createUserApiTypes from &amp;quot;foo&amp;#x2F;api&amp;#x2F;createUser&amp;#x2F;types&amp;quot;;
    const u = new createUserApiTypes.User(req.body.user); 
    # importing, then properly naming, the entire module is in my experience an underutilized tool to help with comprehension.&lt;/code&gt;&lt;/pre&gt;</text></comment>
<story><title>Best practices for TypeScript monorepo</title><url>https://blog.flycode.com/best-practices-for-typescript-monorepo</url></story><parent_chain><item><author>madeofpalk</author><text>&amp;gt; Use Absolute Paths for Importing Code Blocks&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { FormType } from &amp;#x27;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;types&amp;#x2F;form&amp;#x27;;
    import { DateType }   from &amp;#x27;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;..&amp;#x2F;types&amp;#x2F;date&amp;#x27;;
    
    &amp;#x2F;&amp;#x2F; This is considered bad practice
&lt;/code&gt;&lt;/pre&gt;
Disagree on this one. Beauty of typescript is giving you auto-import autocompletion in your editor, and not having to worry about relative paths any more. I don&amp;#x27;t think I&amp;#x27;ve manually written an import statement in years.</text></item></parent_chain><comment><author>bsimpson</author><text>Using relative imports that ..&amp;#x2F; out of your package directory confuses TypeScript about which files are in-scope (and how to structure the resulting files).  You can end up with weird shit like my-library&amp;#x2F;dist&amp;#x2F;my-library&amp;#x2F;index.js.  (I&amp;#x27;m sure you can configure your way out of this.  That&amp;#x27;s a puzzle I haven&amp;#x27;t solved and don&amp;#x27;t intend to invest time into.)&lt;p&gt;Yarn Berry has a node_modules mode now, which makes it behave like Yarn Classic and NPM.  It also allows you to import sibling projects in a monorepo:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    &amp;quot;peerDependencies&amp;quot;: {
      &amp;quot;my-library&amp;quot;: &amp;quot;workspace:*&amp;quot;,
&lt;/code&gt;&lt;/pre&gt;
which means you can&lt;p&gt;&lt;pre&gt;&lt;code&gt;    import { thing } from &amp;#x27;my-library&amp;#x27;
&lt;/code&gt;&lt;/pre&gt;
and have it work as expected, even when my-library is a sibling project in your monorepo.</text></comment>