What you may be used to in other editors is that there is a single behavior you set: tabs or N spaces?
This is not the case with Vim. Vim allows you to define at least three different behaviors that, as we'll see, can actually be mutually exclusive.
P.S. The following is an illustrated guide to the concepts behind tabs and indentation. If you're looking for the TL;DR, feel free to jump to the synopsis.
Here's a frame challenge: in each of the two lines below, where will the cursor go when you press the Tab key?
 
       
      Try to remember how different programs will behave: not just your code editor, but different word processors as well, for example.
The answer:
 
       
      The cursor, for each line, goes to the same column!
You may very well already know this intuitively. One thing you might gloss over, though, is that the Tab character has a different "length" in these two cases!
Hence, the frame challenge. When talking about tabs and spaces in programming, it's easy to fall into the trap of thinking about "tabs vs N spaces". The two aren't actually completely interchangeable!
The reality here is that Tab characters don't inherently have a length. What a Tab character actually does is bring the cursor forward to the next tab stop.
Tab stops can be thought of as markers ("stops") along the page, marking each multiple of a fixed width.
The typical word processor uses a fixed width of half an inch:
 
      Terminals, and thus terminal-based editors, also have a concept of tab stops. The typical terminal uses a width of 8 character blocks, or 8 columns:
 
      :set list.While these are the typical lengths of tab stops, most programs allow users to configure tab stop lengths themselves.
tabstoptabstop option is for: it configures the length of the tab stop.
     
      :set tabstop=4.
    With :set tabstop=4, for example, tab stops will now mark every 4 columns along the line.
    
Notice that we haven't talked about indentation at all yet!
Tab stop length and indentation length can be mutually exclusive. In fact, in certain cases, the settings for both are indeed orthogonal.
    Indentation length is configured separately in Vim with the shiftwidth option.
    
 
      :set shiftwidth=4.This is used by Vim features that are expressly for indenting, such as:
>>: Indent forward, to the right.
      <<: Indent backward, to the left.
      =: The indent operator, e.g. gg=G to fix the whole file's indentation.
      The Tab key is a special case — we'll get to that later.
    While the shiftwidth option tells Vim how many columns to indent a line, it doesn't actually tell Vim how.
    
As programmers well know, a 4-column indent can be created in two ways:
    What governs this choice in Vim is the expandtab option.
    
    With :set expandtab, Vim will use leading Space characters to fulfill the shiftwidth indentation length.
    
    With :set noexpandtab, Vim will do its best to use Tab characters.
    
    There's a minor caveat with :set noexpandtab: if Vim cannot fit Tab characters into the indentation length (such as if shiftwidth is indivisible by tabstop), it uses a mix of Tab and Space characters.
    
 
      The above example uses an indentation length of 6, but with tab stops of 4. The relevant settings would be:
set tabstop=4 shiftwidth=6 noexpandtabIn such a case, Vim indents with a leading Tab character and 2 Space characters.
As I've alluded to above, the Tab key (the key on your keyboard, not the character!) is a special case in Vim.
By default, the Tab key simply inserts a Tab character — no surprise there.
smarttab optionHowever, Vim recognizes that it's popular among programmers to press the Tab key to perform indentation. In fact, it's likely this preconception that led you to some confusion with Vim's tab settings in the first place.
    In light of this, Vim provides another option that can govern Tab key behavior: the smarttab option.
    
    With :set smarttab, the Tab key becomes overloaded with two separate functions:
    
shiftwidth.
      expandtab and softtabstop options...except that's not the whole truth.
    The expandtab option actually governs Tab characters inserted by the Tab key as well!
    
    With :set expandtab, the Tab key will actually insert Space characters. For example, with
    
:set tabstop=8 expandtab
    But what if you want to configure this behavior separately from tabstop? That is where the softtabstop option comes in.
    
For example, with
:set tabstop=8 softtabstop=4 expandtab\x09 in ASCII) will visually display a tab stop length of 8 columns.
    
    There are three distinct but interrelated behaviors regarding tab stops and indentation:
tabstop
      shiftwidth and expandtab
      smarttab, expandtab, and softtabstop
      4-column Tab indents.
 
          :set list.set tabstop=4 shiftwidth=4 noexpandtab
tabstop=4: Make tab stops 4 columns wide.
          shiftwidth=4: Indent 4 columns at a time.
          noexpandtab: Use Tab characters, not Space characters.
          4-column Space indents.
 
          :set list (Spaces are underscores).set shiftwidth=4 expandtab
shiftwidth=4: Indent 4 columns at a time.
          expandtab: Use Space characters, not Tab characters.
          
        Popular with Python. In fact, this is automatically configured in the default ftplugin/python.vim.
        
        The tabstop setting isn't actually needed to achieve 4-column Space indents per se — it's orthogonal.
        
2-column Space indents. Tab stops are 8 columns wide.
 
          :set list.set tabstop=8 shiftwidth=2 expandtab
tabstop=8: Make tab stops 8 columns wide.
          shiftwidth=2: Indent 2 columns at a time.
          expandtab: Use Space characters, not Tab characters.
          This is my Vim setting of choice. 2-column Space indents are a norm in JavaScript code, so that's what I use for indentation.
Orthogonally, I use 8-column-wide tab stops because that's what a lot of terminal output optimizes for: mail clients, Git log viewers, etc.