Sorting C# using Directives: Conventions, Tooling, and .editorconfig Options
The two common conventions for ordering C# using directives, how ReSharper, Rider, StyleCop, Visual Studio, and .editorconfig each support them, and the specific settings that control the behavior.
using directive order is one of those things nobody argues passionately about until a diff full of reordered imports shows up in a PR because two developers’ tools disagreed about the convention. There are really only two common conventions in practice, a handful of rarer variants, and a small set of .editorconfig settings that determine which one your team actually gets.
The two common styles
System directives on top. Namespaces starting with System. come first, alphabetically, followed by everything else, also alphabetically:
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using FluentValidation;
using Xunit;
using Xunit.Sdk;
A common variant adds a blank line between the System group and everything else:
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using FluentValidation;
using Xunit;
using Xunit.Sdk;
Everything mixed together, sorted purely alphabetically with no special treatment for System.*:
using AutoMapper;
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
using Xunit.Sdk;
Where each convention is actually configurable
| Context | Setting supported? | Default | Notes |
|---|---|---|---|
| ReSharper | Yes | System-first | — |
| Rider | Yes | System-first | — |
| StyleCop | Yes | System-first | SA1208 (System first) and SA1210 (alphabetical ordering) |
| Visual Studio | Yes | Mixed/alphabetical | — |
.editorconfig | Yes | — | dotnet_sort_system_directives_first |
Visual Studio’s out-of-the-box default actually differs from ReSharper, Rider, and StyleCop’s default — worth knowing if your team switches between tools and notices using blocks getting reordered unexpectedly.
Rarer variants
A couple of other patterns show up occasionally, though far less often than the two above:
Grouping by System and root namespace, with each logical group separated by a blank line:
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using FluentValidation;
using Xunit;
using Xunit.Sdk;
System on top, but everything else left unsorted:
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using Xunit;
using Xunit.Sdk;
using AutoMapper;
Visual Studio’s relevant option:

The specific .editorconfig settings
Two .editorconfig properties control this behavior directly, and they’re independent of each other.
dotnet_sort_system_directives_first
| Value | Description |
|---|---|
true | Sort System.* using directives alphabetically, and place them before other using directives. |
false | Do not place System.* using directives before other using directives. |
// dotnet_sort_system_directives_first = true
using System.Collections.Generic;
using System.Threading.Tasks;
using Octokit;
// dotnet_sort_system_directives_first = false
using System.Collections.Generic;
using Octokit;
using System.Threading.Tasks;
dotnet_separate_import_directive_groups
| Value | Description |
|---|---|
true | Place a blank line between using directive groups. |
false | Do not place a blank line between using directive groups. |
// dotnet_separate_import_directive_groups = true
using System.Collections.Generic;
using System.Threading.Tasks;
using Octokit;
// dotnet_separate_import_directive_groups = false
using System.Collections.Generic;
using System.Threading.Tasks;
using Octokit;
The takeaway
None of these conventions is objectively correct — the actual goal is that your IDE settings, StyleCop configuration, and .editorconfig all agree with each other, so using blocks don’t shuffle every time a different tool or a different developer touches the file. If you’re setting this up fresh, dotnet_sort_system_directives_first and dotnet_separate_import_directive_groups in .editorconfig are the two settings that actually travel with the repository and apply consistently regardless of which IDE someone’s using — which makes them the right place to anchor the convention, rather than leaving it to per-developer IDE defaults.